我已将项目切换为ARC,但我不明白是否必须使用strong
或weak
作为IBOutlets。 Xcode执行此操作:在界面构建器中,如果创建一个UILabel
并将其与助理编辑器连接到我的ViewController
,则会创建:
@property (nonatomic, strong) UILabel *aLabel;
它使用strong
,而我在RayWenderlich网站上阅读了一个教程,说明了这一点:
但对于这两个特殊的属性我还有其他计划。代替
strong
,我们会将其声明为weak
。
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
Weak
是所有 outlet 属性的推荐关系。 这些视图对象已经是视图控制器视图的一部分 层次结构,不需要保留在别处。最大的优势 宣布你的网点weak
是为了节省你写作的时间 viewDidUnload方法。目前我们的
viewDidUnload
看起来像这样:
- (void)viewDidUnload
{
[super viewDidUnload];
self.tableView = nil;
self.searchBar = nil;
soundEffect = nil;
}
您现在可以将其简化为以下内容:
- (void)viewDidUnload
{
[super viewDidUnload];
soundEffect = nil;
}
因此,请使用weak
而不是strong
,并在videDidUnload
中将设置删除为nil,而不是Xcode使用strong
,并使用{{1在self... = nil
。
我的问题是:我何时必须使用viewDidUnload
,何时使用strong
?
我还想用于部署目标iOS 4,那么我何时必须使用weak
?当使用unsafe_unretain
,strong
和weak
与ARC一起使用时,任何人都可以通过一个小教程向我解释好吗?
答案 0 :(得分:69)
经验法则
当父级具有对子对象的引用时,应使用strong
引用。当子项具有对其父对象的引用时,应使用weak
引用或unsafe_unretained
引用(如果前者不可用)。一个典型的场景是你处理代表。例如,UITableViewDelegate
不保留包含表视图的控制器类。
这里有一个简单的架构来介绍主要概念。
假设第一个A,B和C是strong
个引用。特别是,C对其父级具有strong
ref。当obj1被释放(某处)时,A引用不再存在但是你有泄漏,因为obj1和obj2之间有一个循环。就保留计数而言(仅用于解释目的),obj1的保留计数为2(obj2具有strong
引用),而obj2的保留计数为1。如果释放obj1,则其保留计数现在为1,并且不调用其dealloc
方法。 obj1和obj2仍然留在记忆中,但没有人对它们有任何引用:泄漏。
在contary上,如果只有A和B是strong
refs而C被认定为weak
则一切正常。你没有泄漏。实际上,当obj1被释放时,它也会释放obj2。就保留计数而言,obj1的保留计数为1,obj2的保留计数为1.如果释放obj1,则其保留计数现在为0,并且调用其dealloc
方法。 obj1和obj2从内存中删除。
一个简单的建议:在处理ARC时,开始考虑对象图。
关于您的第一个问题,当您处理XIB时,这两种解决方案都是有效的。通常,在处理内存周期时会使用weak
引用。
关于XIB文件,如果您使用strong
,则需要在nil
中设置viewDidUnload
,因为如果不这样做,在内存不足的情况下,可能会导致意外泄漏。您不会在dealloc
中发布它们,因为ARC会为您执行此操作。
weak
代之以不需要处理,因为当目标对象被销毁时,这些值会自动设置为nil
。没有悬空指针了。
如果您有兴趣,我建议您通过 Mike Ash 阅读friday-qa-2012-04-13-nib-memory-management。
关于第二个问题,如果您需要支持iOS 4而不是weak
,则必须使用unsafe_unretained
。
在SO中有很多问题/答案。这里主要是:
How do I replace weak references when using ARC and targeting iOS 4.0?
What kind of leaks does automatic reference counting in Objective-C not prevent or minimize?
using ARC, lifetime qualifier assign and unsafe_unretained
strong / weak / retain / unsafe_unretained / assign
希望有所帮助。
<强>更新强>
根据shaunlim的评论,从iOS 6开始viewDidUnload
方法已被弃用。在这里,我真的建议看到Rob的回答:iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?。
答案 1 :(得分:11)
对于通过IBOutlets连接到IB中的对象的对象,可以使用weak,因为在这种情况下,只要superview存在,对象就会存在。这是因为superview具有指向其子视图的强指针。
如果您定义的指针是指向对象的唯一指针,则应将其声明为强。
如果您是注册开发人员,我强烈建议您查看WWDC11和WWDC12中的视频。另一个很好的资源是来自Stanford.
的iOS开发播客