iOS5 ARC,IBOutlets 应该定义strong还是weak

原帖: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) 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属性

[cpp] view plaincopyprint?

  1. #import
  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

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

[cpp] view plaincopyprint?

  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做下工作:

[cpp] view plaincopyprint?

  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

时间: 2024-11-03 03:25:56

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

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

iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的. 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都很熟悉了,在此我也不介绍,网上有很多相关文章. 现在我们看看iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained功能差不多(有点区别,等下会介绍,这两个新 关键字与

objective-c中ARC环境下的strong与weak的原理

一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编译器为你处理了一切 注意:ARC 是编译器特性,而不是 iOS 运行时特性(除了weak指针系统),它也不是类似于其它语言中的垃圾收集器.因此 ARC 和手动内存管理性能是一样的,有时还能更加快速,因为编译器还可以执行某些优化 二.原理 ARC 的规则非常简单:只要还有一个变量指向对象,对象就会保持

ARC - strong和weak指针

ARC指南1 - strong和weak指针 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量" 一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编译器为你处理了一切 注意:ARC 是编译器特性,而不是 iOS 运行时特性(除了weak指针系统),它也不

iOS开发-assign、retain、copy、strong、weak的区别

对于初学的开发者,对于assign.retain.copy.strong.weak的用法及意义可能不是很明白,我对于这个问题也研究了很久,写篇博文,巧巧代码,让我们来瞧瞧吧! 先定义一个Student类: #import <Foundation/Foundation.h> @interface Student : NSObject @property (nonatomic, copy) NSString *name; @end 然后先是mrc下的assign声明 @property (nona

strong和weak

在iOS开发的过程中,我们一般不用retain,和assign,而是用strong和weak,这时候,我们可以把strong理解为retain,而weak理解为assign,比较容易理解. 在ARC情况下: Strong 和weak: 如果一个对象同时被两个指针所引用,例如: Object *b1 = [[Object alloc]initAge:23]; Object *b2 = b1;    1. 如果你在property里面声明的是strong,那么这个就是强引用, 在进行赋值的时候,对象

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

有人问.在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 ob

[转载]IOS开发之----strong和weak (IOS5新特性)

iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的. 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都很熟悉了,在此我也不介绍,网上有很多相关文章. 现在我们看看iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained功能差不多(有点区别,等下会介绍,这两个新关键字与a

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

Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量" 一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编译器为你处理了一切 注意:ARC 是编译器特性,而不是 iOS 运行时特性(除

IOS5中strong和weak的用法

iOS 5 中对属性的设置新增了strong 和weak关键字来修饰属性(iOS 5 之前不支持ARC) strong 用来修饰强引用的属性: @property (strong) SomeClass * aObject; 对应原来的 @property (retain) SomeClass * aObject; 和 @property (copy) SomeClass * aObject; weak 用来修饰弱引用的属性:@property (weak) SomeClass * aObject