代表 - 保留或分配 - 释放?

Posted

技术标签:

【中文标题】代表 - 保留或分配 - 释放?【英文标题】:Delegates - retain or assign - release? 【发布时间】:2011-06-15 07:35:50 【问题描述】:

我看过许多与代表相关的帖子,我想知道引用它们的正确方法。假设我有一个声明如下的对象:

@interface MyViewController : UITableViewController 
    id delegate;    

@property (nonatomic, retain) id delegate;
@end

通过MyViewController 的生命周期,它将调用其委托的方法以响应与用户的交互。

当需要删除MyViewController 的实例时,delegate ivar 是否需要在实现的dealloc 方法中进行release'ed,因为它是用retain 声明的?

或者相反,是否应该保留delegate?也许应该是@property (nonatomic, assign) id delegate?根据Apple's docs:

retain ...您通常将此属性用于标量类型,例如 NSInteger 和 CGRect,或者(在引用计数环境中)用于您不拥有的对象,例如委托。

通常我会按照文档所说的进行,但我看到很多代码在委托上调用 retain。这只是“糟糕的代码”吗?我听从这里的专家……处理这个问题的正确方法是什么?

【问题讨论】:

【参考方案1】:

您通常希望分配委托而不是保留它们,以避免在对象 A 保留对象 B 和对象 B 保留对象 A 的情况下循环保留计数。(您可能会看到这被称为保留对委托。)例如,考虑以下常见模式:

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

如果utilityObjectdelegate 属性都使用retain 声明,则self 现在保留self.utilityObjectself.utilityObject 保留self

有关更多信息,请参阅Why are Objective-C delegates usually given the property assign instead of retain?。

如果您分配委托而不是保留它,那么您无需担心在 dealloc 中释放它。

【讨论】:

【参考方案2】:

这通常表明设计不佳,因为大多数委托保留了它们的对象(造成保留循环的可能性,从而导致泄漏。)但在某些情况下,对象应该保留其委托。这些通常是对象没有可用引用的情况,因此委托不能保留它 - 但它本身有时可能表明设计不佳。

【讨论】:

【参考方案3】:

我也听到了很多关于这个的意见。我不知道正确的方法,但我可以告诉你我通过自己的工作得到了什么。

你想retain 任何你需要保留你的句柄的东西。在引用计数环境中,这就是所有所有权。这是一个声明,“我稍后会需要这个,不要让它消失在我身上”。

这还意味着您有责任解除对它的索赔。如果您不专门这样做,那么您很容易出现各种问题,尤其是在处理可能很好地保留他们作为委托的对象的委托时。如果您不处理保留的委托,所有权将是循环的,并且对象会泄漏。但是不要忘记释放你保留的东西,你会没事的。

【讨论】:

以上是关于代表 - 保留或分配 - 释放?的主要内容,如果未能解决你的问题,请参考以下文章

目标 C:保留/释放内联分配的对象

将自动释放的对象分配给保留的属性

@property(保留)是不是自动释放或释放对象?

内存保留和释放

自动释放对象递减的保留计数何时减少?

将numpy数组设置为无释放内存吗?