31

我已经将我的项目切换到ARC,并且我不明白如果必须使用strongweak用于IBOutlets。 Xcode中做到这一点:在界面生成器,如果创建例如UILabel,我与助理编辑将它连接到我的ViewController,它创建此:IBOutlet和其他弱或强

@property (nonatomic, strong) UILabel *aLabel; 

它使用strong,而不是我读RayWenderlich网站的教程说这个:

但是对于这两个特定的属性,我有其他计划。我们会将其声明为weak,而不是 strong

@property (nonatomic, weak) IBOutlet UITableView *tableView; 
@property (nonatomic, weak) IBOutlet UISearchBar *searchBar; 

Weak是所有出口属性推荐关系。 这些视图对象已经是视图控制器视图 层次结构的一部分,并且不需要保留在别处。宣布您的网点weak的最大优势 是可以节省您编写012DXviewDidUnload方法的时间。

目前我们viewDidUnload看起来是这样的:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    self.tableView = nil; 
    self.searchBar = nil; 
    soundEffect = nil; 
} 

现在就可以简化为以下几点:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    soundEffect = nil; 
} 

因此,使用weak,而不是strong,和在videDidUnload中删除设置为零,而不是Xcode使用th e strong,并在viewDidUnload中使用self... = nil

我的问题是:我什么时候必须使用strong,而当weak? 我也想用于部署目标iOS 4,那么我何时必须使用unsafe_unretain?当使用strong,weakunsafe_unretain时,任何人都可以用一个小教程来帮助我解释一下吗?

回答

69

的iOS开发的播客拇指

当父母有到子对象的引用,你应该使用strong参考的规则。当孩子参考其父对象时,应该使用weak引用或unsafe_unretained(如果前者不可用)。典型的情况是当你与代表打交道时。例如,UITableViewDelegate不保留包含表视图的控制器类。

enter image description here

这里一个简单的模式来呈现的主要概念。

假设第一个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从内存中删除。

一个简单的建议:在处理ARC时开始考虑对象图。

关于你的第一个问题,当你处理XIB时,两种解决方案都是有效的。在处理内存周期时,通常会使用weak引用。 关于XIB文件,如果使用strong,则需要在viewDidUnload中设置nil,因为如果不这样做,则在内存不足的情况下,可能会导致意外泄漏。你不会在dealloc中发布它们,因为ARC会为你做。 weak而不需要这种处理,因为当目标对象被破坏时,这些值自动设置为nil。没有悬挂指针了。

如果您有兴趣,我建议您通过来阅读friday-qa-2012-04-13-nib-memory-management Mike Ash

关于第二个问题,如果您需要支持iOS 4,而不是weak,则必须使用unsafe_unretained

因此,有很多问题/答案。这里主要有:

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?

+0

感谢答案 – Piero

+0

你说,对于iboutlet,如果我使用强壮,我必须在viewdidunload中使用nil,而对于低内存,我没有泄漏,而使用weak,我不必在videwdidunlaod中使用nil,对于低内存警告最好是强大的解决方案还是弱点? – Piero

+0

这是一样的。使用'weak'可以节省手工编写代码的时间(两行代码)。但是,Xcode为你做。我个人的意见。我喜欢用'strong'。 –

11

对于通过IBOutlets连接到IB中的对象的对象,您可以使用weak,因为在这种情况下,只要超级视图存在,对象就会在那里。这是因为超级视图有强烈的指向子视图的指针。

如果你正在定义的指针是指向一个对象的唯一指针,你应该声明它为强。

如果您是注册开发者,我强烈建议您查看WWDC11和WWDC12中的视频。另一个很好的资源是从Stanford.

+0

WWDC12视频是否可用? – borrrden

+0

是的,他们是!今年真的很快。 – dasdom

+0

好的,但我不明白,我的问题覆盖也unsafe_unretain,但对于IBOutlet我很好解释,为什么苹果使用强?...而不是使用弱?...所以我必须遵循苹果?或遵循raywenderlich教程,我写上面使用弱的代码片段? – Piero