转自:http://blog.csdn.net/yiyaaixuexi/article/details/7864974

写这篇文章的缘由,是因为我泡在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)IBOutletMyView*viewContainerSubview;@property(strong)IBOutletMyOtherClass*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属性

  1. #import <UIKit/UIKit.h>
  2. @interface TestViewController : UIViewController
  3. {
  4. BOOL isShowing;
  5. }
  6. @property (nonatomic,weak)IBOutlet UIBarButtonItem *controlBtn;
  7. @property (nonatomic,weak)IBOutlet UIBarButtonItem *cameraBtn;
  8. -(IBAction)controlAction:(id)sender;
  9. @end

用右侧按钮,控制相机按钮的隐藏和显示:

  1. #import "TestViewController.h"
  2. @interface TestViewController ()
  3. @end
  4. @implementation TestViewController
  5. @synthesize cameraBtn,controlBtn;
  6. - (void)viewDidLoad
  7. {
  8. [super viewDidLoad];
  9. // Do any additional setup after loading the view, typically from a nib.
  10. isShowing = YES;
  11. }
  12. - (void)viewDidUnload
  13. {
  14. [super viewDidUnload];
  15. // Release any retained subviews of the main view.
  16. }
  17. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  18. {
  19. return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
  20. }
  21. -(IBAction)controlAction:(id)sender
  22. {
  23. if (isShowing) {
  24. self.controlBtn.title = @"显示相机";
  25. self.navigationItem.leftBarButtonItem = nil;
  26. isShowing = NO;
  27. }else {
  28. self.controlBtn.title = @"隐藏相机";
  29. self.navigationItem.leftBarButtonItem = cameraBtn;
  30. isShowing = YES;
  31. }
  32. }
  33. @end

实验结果是,第一次隐藏了相机按钮后,就再也显示不出来了。原因很简单,cameraBtn指向了空,我们丢失了cameraBtn的对象所有权。

解决问题的办法有两个:

1.不在xib或者storyboard上拖相机按钮,而是用代码创建,自己控制对象所有权

2.将 cameraBtn 定义为strong

我想强调的当然是第二种方法,当然了,改成strong后,相应的也需要配合ARC做下工作:

  1. - (void)viewDidUnload
  2. {
  3. [super viewDidUnload];
  4. // Release any retained subviews of the main view.
  5. self.cameraBtn = nil;
  6. }

顺便提一下ARC其他属性的规则:

  • strong:等同于"retain",属性成为对象的拥有者

  • weak:属性是 weak pointer,当对象释放时会自动设置为 nil

  • unsafe_unretained:等同于之前的"assign",只有 iOS 4 才应该使用

  • copy:和之前的 copy 一样,复制一个对象并创建 strong 关联

  • assign:对象不能使用 assign,但原始类型(BOOL、int、float)仍然可以使用

最后一句,记忆规则,理解规则,善用规则。

iOS5 ARC,IBOutlets 应该定义strong还是weak的更多相关文章

  1. iOS5 ARC学习笔记:strong、weak等详解

    2013-03-25 13:41 佚名 oschina 字号:T | T iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的.现在我们看看iOS5 ...

  2. ARC机制中的Strong和weak

    什么是ARC Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化.ARC是新的LLVM 3.0编译 ...

  3. ARC - strong和weak指针

    ARC指南1 - strong和weak指针   提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量&qu ...

  4. 何时使用copy,strong,weak,assign关键字 定义属性

    现在我们看看iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained ...

  5. 【iOS开发系列】XIB IBOutlets use strong or weak ?

    有人问.在ARC下,IBOutlets究竟应该定义成strong 还是 weak ?支持这个答案的人最多.答案仅是摘自官方文档的一个片段: From a practical perspective, ...

  6. ARC指南1 - strong和weak指针

      一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因 ...

  7. ARC指南 strong和weak指针

    一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编 ...

  8. (转)ARC指南 - strong、weak指针

    一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编 ...

  9. Objective-C中,ARC下的 strong和weak指针原理解释

    Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是& ...

随机推荐

  1. vagrant public_network 自定义静态 ip配置方法

    Vagrant 创建虚拟化开发环境 Vagrant是一个基于Ruby的工具,用于创建和部署虚拟化开发环境.它 使用Oracle的开源VirtualBox虚拟化系统,使用 Chef创建自动化虚拟环境. ...

  2. 【转载】【Todo】电商架构相关技术分析

    看了一篇文章: http://kb.cnblogs.com/page/193670/    淘宝应对"双11"的技术架构分析 没怎么看懂,有时间再看.

  3. centos7 安装selenium和firefox

    之前有一篇文章介绍过在ubuntu下安装selenium和firefox 现在介绍下centos7 注意以下都是下载的linux64位的软件,32位的请自己找下链接, 现在使用的python的版本是3 ...

  4. http://www.blogjava.net/crespochen/archive/2011/04/22/348819.html

    http://blog.csdn.net/supersky07/article/details/7407523 http://blog.csdn.net/cuker919/article/detail ...

  5. No_16_0324 Java基础学习第二十三天

    文档版本号 开发工具 測试平台 project名字 日期 作者 备注 V1.0 2016.03.24 lutianfei none 登录注冊IO版 例如以下代码仅为UserDaoImpl类文件,其它原 ...

  6. 让网页在ie浏览器下以最高版本解析网页

    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta ht ...

  7. 职场二年级转型C++的困惑

    [来信] 老师.你好.看了你的博客和採訪.不由主自地给你发私信,感觉你能解答我的问题. 学生90后,2012年毕业于某不知名院校.两年工作经验(第一年C#,第二年java,直到如今),一直想转型C++ ...

  8. 说说C#之父——安德斯·海尔斯伯格

    安德斯·海尔斯伯格(Anders Hejlsberg,1960.12~),丹麦人,Turbo Pascal编译器的主要作者,Delphi和.NET之父! 看到照片的那一刹那儿,我就觉得帅爆了,53岁的 ...

  9. 使用jsmin压缩javascript脚本

    官方地址:http://www.crockford.com/javascript/jsmin.html 点击页下方的”zip file containing an MS-DOS.exe file“下载 ...

  10. 使用gradle构建Android时 版本号versionName中嵌入git提交信息

    为什么要这么做   在应用开发的版本迭代过程中,通过版本号并不能快速定位到所对应的代码,导致在后面分析问题追溯对应版本的代码时比较麻烦.   如果代码是通过git来管理的,git的commit id等 ...