委托 - 使用retain还是assign - 释放?

13

我看到了很多关于委托的帖子,我想知道正确的引用方式。假设我声明了一个对象,如下所示:

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

MyViewController的生命周期内,它将根据用户的交互调用其委托的方法。

当需要摆脱MyViewController实例时,由于它是使用retain声明的,因此在实现的dealloc方法中是否需要释放delegate ivar?

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

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

通常我会遵循文档所说的做法,但我看到了很多调用委托的retain代码。这只是"bad code"吗?我听从专家的意见... 应该如何正确处理这个问题?

3个回答

21

通常情况下,您应该分配代理而不是保留它们,以避免循环保留计数,其中对象A保留对象B,而对象B保留对象A。(您可能会看到这被称为保持对代理的“弱引用”。)例如,请考虑以下常见模式:

-(void)someMethod {
    self.utilityObject = [[[Bar alloc] init] autorelease];
    self.utilityObject.delegate = self;
    [self.utilityObject doSomeWork];
}
如果使用retain声明utilityObjectdelegate属性,则self现在会保留self.utilityObject,而self.utilityObject会保留self
更多相关信息请参考:为什么Objective-C代理通常使用assign属性而不是retain? 如果分配委托对象而不是保留它,则无需担心在dealloc中释放该对象。

1

这通常表明设计不良,因为大多数委托会保留它们的对象(从而创建潜在的保留循环和泄漏)。但是有些情况下,一个对象应该保留它的委托。这些通常是没有对该对象的引用可用的情况,因此委托不能成为保留它的对象 - 但这本身有时可能表明设计不良。


0

关于这个问题我也听了很多不同的意见。我不知道什么是正确的方法,但我可以通过我的工作告诉你我的想法。

你需要 保留 需要保存的任何内容,这就是在引用计数环境中所有权的含义。这意味着:“我以后还需要这个,不要让它丢失”。

这也意味着你有责任释放你对它的所有权。如果你没有明确地做到这一点,你将面临各种问题,尤其是处理可能会保留其所委托对象的委托。如果你没有处理好对委托的保留,所有权将是循环的,对象将泄漏。但不要忘记释放你所保留的东西,这样你就没问题了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接