对于IBOutlet和其他
我已经将我的项目切换到了ARC,而且我不明白我是否必须使用IBOutlet strong
或weak
。 Xcode做到这一点:在界面生成器中,如果创build一个UILabel
例如,我将其与助理编辑器连接到我的ViewController
,它创build此:
@property (nonatomic, strong) UILabel *aLabel;
它使用strong
,而是我阅读RayWenderlich网站上的一个教程,说:
但是对于这两个特定的属性我有其他的计划。 我们将宣布它们变
weak
,而不是strong
。
@property (nonatomic, weak) IBOutlet UITableView *tableView; @property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
所有出口物业的推荐关系都
Weak
。 这些视图对象已经是视图控制器视图层次结构的一部分,不需要保留在其他地方。 声明您的网点weak
的一大优点是可以节省您编写viewDidUnload方法的时间。目前我们的
viewDidUnload
如下所示:
- (void)viewDidUnload { [super viewDidUnload]; self.tableView = nil; self.searchBar = nil; soundEffect = nil; }
现在可以将其简化为以下内容:
- (void)viewDidUnload { [super viewDidUnload]; soundEffect = nil; }
因此,使用weak
,而不是strong
,并将设置为零在videDidUnload
,而不是Xcode使用strong
,并使用self... = nil
在viewDidUnload
。
我的问题是:什么时候我必须使用strong
,什么时候weak
? 我也想用于部署目标iOS 4,那么我什么时候必须使用unsafe_unretain
? 任何人都可以帮助解释一个小教程,当使用strong
, weak
和unsafe_unretain
与弧?
经验法则
当父对象具有对子对象的引用时,应该使用strong
引用。 当一个孩子有一个对其父对象的引用时,你应该使用一个weak
引用或一个unsafe_unretained
(如果前者不可用)。 一个典型的情况是当你与代表打交道的时候。 例如, UITableViewDelegate
不保留包含表视图的控制器类。
这里有一个简单的模式来介绍主要的概念。
假设第一个A,B和C是strong
引用。 特别是,C有一个strong
参考其父母。 当obj1被释放(某处)时,A引用不再存在,但是由于obj1和obj2之间有一个循环,所以你有泄漏。 在保留计数( 仅用于解释目的 )方面,obj1的保留计数为2(obj2对此有strong
参考),而obj2的保留计数为1.如果obj1被释放,则其保留计数现在为1并且它的dealloc
方法不被调用。 obj1和obj2仍然留在记忆中,但没有人提到他们: 泄漏 。
如果只有A和B是strong
裁判,而C是weak
一切都可以。 你没有泄漏。 事实上,当obj1被释放时,它也释放obj2。 就保留计数而言,obj1的保留计数为1,obj2的保留计数为1.如果释放obj1,则其保留计数现在为0,并调用其dealloc
方法。 obj1和obj2从内存中删除。
一个简单的build议:当你处理ARC时开始考虑对象图。
关于你的第一个问题,当你处理XIB时,这两个解决scheme都是有效的。 在处理内存周期时,通常使用weak
引用。 关于XIB文件,如果你使用strong
你需要在viewDidUnload
设置nil
,因为如果你不这样做,在内存不足的情况下,你可能会导致意想不到的泄漏。 你不会在dealloc
释放它们,因为ARC会为你做。 weak
而不需要这种处理,因为当目标对象被破坏时,这些值被自动设置nil
。 没有悬挂指针了。
如果您有兴趣,我真的build议您阅读Mike Ash的 friday-qa-2012-04-13-nib-memory-management 。
关于你的第二个问题,如果你需要支持iOS 4,而不是weak
你必须使用unsafe_unretained
。
在这里面有很多问题/答案。 这里主要的是:
如何在使用ARC并定位iOS 4.0时replace弱引用?
Objective-C中的自动引用计数不会阻止或最小化什么样的泄漏?
使用ARC,生命周期限定符分配和unsafe_unretained
强/弱/保留/ unsafe_unretained / assign
希望有所帮助。
更新
根据shaunlim的评论,从iOS 6开始, viewDidUnload
方法已被弃用。 在这里我真的build议看看Rob的回答: iOS 6 – viewDidUnload迁移到didReceiveMemoryWarning? 。
对于通过IBOutlets连接到IB中的对象的对象,可以使用weak,因为在这种情况下,只要superview在那里,对象就会在那里。 这是因为superview有强烈的指向子视图的指针。
如果你正在定义的指针是指向一个对象的唯一指针,你应该声明它为强。
如果您是注册开发人员,我强烈build议您查看WWDC11和WWDC12中的video。 另一个很好的资源是来自斯坦福大学的iOS开发播客。