iOS5 ARC,IBOutlets 应该定义strong还是weak
来源:互联网 发布:淘宝html模板 编辑:程序博客网 时间:2024/05/17 23:16
写这篇文章的缘由,是因为我泡在stackoverflow上翻帖子,看到一个名为Should IBOutlets be strong or weak under ARC? 的帖子很热,而我对被采纳为标准答案的回答也有一些话要补充,我想对于每一个初识ARC模式的人来说,都会有这个疑问,所以不妨我也来和大家探讨一下。
有人问,在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).
@property (weak) IBOutlet MyView *viewContainerSubview;@property (strong) IBOutlet MyOtherClass *topLevelObject;
大意是说,在 ARC 中,一般outlet属性都推荐使用 weak,应该使用 strong 的 outlet 是 File's Owner连接到 nib 的顶层对象。
什么是 File's Owner连接到 nib 的顶层对象呢?说白话一点,就是自定义的view,不是直接作为main view里面一个sub view直接显示出来,而是需要通过实例化创建出来的。你自己实例化,当然需要strong了,不然谁还替你保留对象所有权呢?
以上的分析都没有错,但是总觉得少了点什么。对于到底是weak 还是 strong,归根结底,还是要刨到对对象所有权的问题上,但是不便于总结出浅显易懂的规律性使用法则。于是,就会有一个又一个的特例打破文档所总结的常规,不明白规则的根是什么,还是会碰到麻烦的。
我来举一个简单的例子,创建一个程序入口指向navigation controller的工程,导航栏上拖2个按钮:
右侧按钮用于控制相机按钮的显示与否,按照文档的指示,我们在程序中定义这两个按钮应为weak属性
- #import <UIKit/UIKit.h>
- @interface TestViewController : UIViewController
- {
- BOOL isShowing;
- }
- @property (nonatomic,weak)IBOutlet UIBarButtonItem *controlBtn;
- @property (nonatomic,weak)IBOutlet UIBarButtonItem *cameraBtn;
- -(IBAction)controlAction:(id)sender;
- @end
用右侧按钮,控制相机按钮的隐藏和显示:
- #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;
- }
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- }
- -(IBAction)controlAction:(id)sender
- {
- if (isShowing) {
- self.controlBtn.title = @"显示相机";
- self.navigationItem.leftBarButtonItem = nil; //导致相机按钮显示不出来的原因(释放了leftBarButtonItem),add by cc
- isShowing = NO;
- }else {
- self.controlBtn.title = @"隐藏相机";
- self.navigationItem.leftBarButtonItem = cameraBtn;
- isShowing = YES;
- }
- }
- @end
实验结果是,第一次隐藏了相机按钮后,就再也显示不出来了。原因很简单,cameraBtn指向了空,我们丢失了cameraBtn的对象所有权。
解决问题的办法有两个:
1.不在xib或者storyboard上拖相机按钮,而是用代码创建,自己控制对象所有权
2.将 cameraBtn 定义为strong
我想强调的当然是第二种方法,当然了,改成strong后,相应的也需要配合ARC做下工作:
- - (void)viewDidUnload
- {
- [super viewDidUnload];
- // Release any retained subviews of the main view.
- self.cameraBtn = nil;
- }
顺便提一下ARC其他属性的规则:
strong:等同于"retain",属性成为对象的拥有者
weak:属性是 weak pointer,当对象释放时会自动设置为 nil
unsafe_unretained:等同于之前的"assign",只有 iOS 4 才应该使用
copy:和之前的 copy 一样,复制一个对象并创建 strong 关联
assign:对象不能使用 assign,但原始类型(BOOL、int、float)仍然可以使用
一些评论:
1. 使用IBOutlet之后(不设置成weak),对于xib文件中的创建的控件,viewcontroller与view都会强应用该控件,等于该控件的引用计数为2。在内存过小警告释放view时,会导致该控件引用计数只减去了1,该控件没有随view一起被释放(viewcontroller还强引用着它),导致内存泄露,所以需要显式在viewDidUnload中将此控件=nil,释放之。或者直接设置成weak,这样,view被释放时此控件也一起被释放了。
2. 感觉self.navigationItem.leftBarButtonItem = nil; 不是很合适,在arc中就等于直接给释放了,所以就丢失了引用。这里的需求只是不显示而已,用hidden=YES是不是更好?
一点意见,欢迎讨论
- iOS5 ARC,IBOutlets 应该定义strong还是weak
- iOS5 ARC,IBOutlets 应该定义strong还是weak
- iOS5 ARC,IBOutlets 应该定义strong还是weak
- iOS5 ARC,IBOutlets 应该定义strong还是weak
- iOS5 ARC,IBOutlets 应当定义strong还是weak
- 在ARC下,IBOutlets到底应该定义成strong 还是 weak ?
- iOS5 ARC strong weak
- iOS5 strong, weak, unsafe_unretained ARC
- iOS5 strong, weak, unsafe_unretained ARC
- iOS5 strong, weak, unsafe_unretained ARC
- iOS5 strong, weak, unsafe_unretained ARC
- iOS5 strong, weak, unsafe_unretained ARC
- Should IBOutlets be strong or weak under ARC
- ios开发ARC,IBOutlets之strong与weak
- ios开发ARC,IBOutlets之strong与weak
- Should IBOutlets be strong or weak under ARC?
- Should IBOutlets be strong or weak under ARC?
- ios开发ARC,IBOutlets之strong与weak
- 3.循环队列(数组)
- StringUtils类
- android 调试
- AFNetworking图片异步加载
- 面试必备的9大成功秘诀
- iOS5 ARC,IBOutlets 应该定义strong还是weak
- USB协通讯议--深入理解
- 分布式计算开源框架Hadoop入门实践
- 如何解决mysql导入数据乱码问题
- ibatis返回HashMap类型结果时自动把Integer类型数据转变成BigDecimal类型
- 工作中,如何做带教老师
- linux内核启动代码分析
- Oracle利用SQL*PLUS的spool功能抽取数据
- org.apache.tomcat.util.bcel.classfile.ClassFormatException: null is not a Java .class file