对于IBOutlet和其他

我已经将我的项目切换到了ARC,而且我不明白我是否必须使用IBOutlet strongweak 。 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... = nilviewDidUnload

我的问题是:什么时候我必须使用strong ,什么时候weak ? 我也想用于部署目标iOS 4,那么我什么时候必须使用unsafe_unretain ? 任何人都可以帮助解释一个小教程,当使用strongweakunsafe_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开发播客。