IBOutlet和其他弱者或弱者

时间:2012-06-23 10:55:02

标签: ios ios5 automatic-ref-counting weak-references strong-references

我已将项目切换为ARC,但我不明白是否必须使用strongweak作为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_unretainstrongweak与ARC一起使用时,任何人都可以通过一个小教程向我解释好吗?

2 个答案:

答案 0 :(得分:69)

经验法则

当父级具有对子对象的引用时,应使用strong引用。当子项具有对其父对象的引用时,应使用weak引用或unsafe_unretained引用(如果前者不可用)。一个典型的场景是你处理代表。例如,UITableViewDelegate不保留包含表视图的控制器类。

enter image description here

这里有一个简单的架构来介绍主要概念。

假设第一个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开发播客