简体   繁体   English

代表 - 保留或分配 - 发布?

[英]Delegates - retain or assign - release?

I've seen a number of posts related to delegates, and I would like to know the proper way to reference them. 我见过很多与代表有关的帖子,我想知道引用它们的正确方法。 Suppose I have an object declared like: 假设我有一个声明为的对象:

@interface MyViewController : UITableViewController {
    id delegate;    
}
@property (nonatomic, retain) id delegate;
@end

Through the lifecycle of MyViewController , it will make calls to methods of its delegate in response to interaction with the user. 通过MyViewController的生命周期,它将调用其委托的方法以响应与用户的交互。

When it's time to get rid of an instance of MyViewController , does the delegate ivar need to be release 'ed in the implementation's dealloc method since it is declared with retain ? 当它摆脱的一个实例的时间MyViewController ,莫非delegate伊娃需要被release在执行的“编dealloc方法,因为它是与声明retain

Or conversely, should delegate even be retained? 或者相反, delegate甚至应该保留? Perhaps it should be @property (nonatomic, assign) id delegate ? 也许它应该是@property (nonatomic, assign) id delegate According to Apple's docs : 根据Apple的文档

retain ... You typically use this attribute for scalar types such as NSInteger and CGRect, or (in a reference-counted environment) for objects you don't own such as delegates. retain ...您通常将此属性用于标量类型(如NSInteger和CGRect),或者(在引用计数环境中)用于您不拥有的对象(如委托)。

Normally I'd just go with what the docs say, but I've seen a lot of code that calls retain on a delegate. 一般情况下我刚刚去与文档说什么,但我已经看到了很多的代码,它retain一个委托。 Is this just "bad code?" 这只是“糟糕的代码吗?” I defer to the experts here... What is the proper way to handle this? 我在这里请专家......处理这个问题的正确方法是什么?

You generally want to assign delegates rather than retain them, in order to avoid circular retain counts where object A retains object B and object B retains object A. (You might see this referred to as keeping a "weak reference" to the delegate.) For example, consider the following common pattern: 您通常希望分配代理而不是保留它们,以避免循环保留计数,其中对象A保留对象B并且对象B保留对象A.(您可能会看到这被称为保留对代理的“弱引用”。)例如,请考虑以下常见模式:

-(void)someMethod {
    self.utilityObject = [[[Bar alloc] init] autorelease];
    self.utilityObject.delegate = self;
    [self.utilityObject doSomeWork];
}

if the utilityObject and delegate properties are both declared using retain , then self now retains self.utilityObject and self.utilityObject retains self . 如果utilityObjectdelegate属性都使用retain声明,则self现在保留self.utilityObjectself.utilityObject保留self

See Why are Objective-C delegates usually given the property assign instead of retain? 请参阅为什么Objective-C代理通常给予属性赋值而不是保留? for more on this. 了解更多。

If you assign the delegate rather than retaining it then you don't need to worry about releasing it in dealloc. 如果您分配代理而不是保留它,那么您不必担心在dealloc中释放它。

It is usually indicative of bad design, since most delegates retain their objects (creating the potential for retain loops and thus leaks.) But there are some cases where an object should retain its delegate. 它通常表示设计不好,因为大多数代表保留其对象(创建保留循环的可能性,从而泄漏。)但在某些情况下,对象应保留其委托。 These are usually cases where no reference is available to the object, so the delegate cannot be the one to retain it--but that itself can sometimes indicate bad design. 这些通常是对象没有可用引用的情况,因此委托不能保留它 - 但这本身有时可能表示设计不良。

I've heard a lot of opinions on this as well. 我也听过很多意见。 I don't know the Right Way, but I can tell you what I've arrived at through my own work. 我不知道正确的方法,但我可以告诉你我通过自己的工作得到了什么。

You want to retain anything that you need to preserve your handle on. 您希望retain保留句柄所需的任何内容。 That's all ownership is, in a reference-counted environment. 在参考计算环境中,所有权都是。 It's a declaration that "I'll need this later, don't let it go away on me". 这是一个声明,“我以后需要这个,不要让它消失在我身上”。

That ALSO means you're responsible for releasing your claim on it. ALSO意味着您有责任发布您的索赔。 If you don't specifically do that, you're prone to various problems, but especially dealing with delegates which might well retain the object they're a delegate of. 如果你没有专门做到这一点,你就会遇到各种各样的问题,尤其是处理那些可能会保留他们所代表的对象的代表。 If you don't deal with your retention of the delegate, the ownership will be cyclical and the objects will leak. 如果您不处理您对代理人的保留,则所有权将是周期性的,并且对象将泄漏。 But don't forget to release what you retain, and you'll be okay. 但是别忘了释放你保留的东西,你会没事的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM