有人问。在ARC下,IBOutlets究竟应该定义成strong 还是 weak ?支持这个答案的人最多。答案仅是摘自官方文档的一个片段:
From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because:
-
Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership.
-
The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet).
-
大意是说。在 ARC 中,一般outlet属性都推荐使用 weak,应该使用 strong 的 outlet 是 File's Owner连接到 nib 的顶层对象。
什么是 File's Owner连接到 nib 的顶层对象呢?说白话一点。就是自己定义的view,不是直接作为main view里面一个sub view直接显示出来。而是须要通过实例化创建出来的。
你自己实例化。当然须要strong了,不然谁还替你保留对象全部权呢?
以上的分析都没有错,可是总认为少了点什么。
对于究竟是weak 还是 strong,归根结底,还是要刨到对对象全部权的问题上,可是不便于总结出浅显易懂的规律性使使用方法则。于是。就会有一个又一个的特例打破文档所总结的常规,不明确规则的根是什么,还是会碰到麻烦的。
我来举一个简单的样例,创建一个程序入口指向navigation controller的project,导航栏上拖2个button:
右側button用于控制相机button的显示与否。依照文档的指示。我们在程序中定义这两个button应为weak属性
#import @interface TestViewController : UIViewController { BOOL isShowing; } @property (nonatomic,weak)IBOutlet UIBarButtonItem *controlBtn; @property (nonatomic,weak)IBOutlet UIBarButtonItem *cameraBtn; -(IBAction)controlAction:(id)sender; @end
用右側button,控制相机button的隐藏和显示:
#import "TestViewController.h" @interface TestViewController () @end @implementation TestViewController @synthesize cameraBtn,controlBtn; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. isShowing = YES; } -(IBAction)controlAction:(id)sender { if (isShowing) { self.controlBtn.title = @"显示相机"; self.navigationItem.leftBarButtonItem = nil; isShowing = NO; }else { self.controlBtn.title = @"隐藏相机"; self.navigationItem.leftBarButtonItem = cameraBtn; isShowing = YES; } } @end
实验结果是。第一次隐藏了相机button后,就再也显示不出来了。原因非常easy,cameraBtn指向了空。我们丢失了cameraBtn的对象全部权。
解决这个问题的办法有两个:
1.不在xib或者storyboard上拖相机button,而是用代码创建,自己控制对象全部权
2.将 cameraBtn 定义为strong
我想强调的当然是另外一种方法
顺便提一下ARC其它属性的规则:
-
strong:等同于"retain",属性成为对象的拥有者
-
weak:属性是 weak pointer,当对象释放时会自己主动设置为 nil
-
unsafe_unretained:等同于之前的"assign",仅仅有 iOS 4 才应该使用
-
copy:和之前的 copy 一样,复制一个对象并创建 strong 关联
-
assign:对象不能使用 assign,但原始类型(BOOL、int、float)仍然能够使用