iOS的属性声明:retain和strong的区别

  声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong)。不过在声明Block时,使用strong和retain会有截然不同的效果。strong会等于copy,而retain竟然等于assign!

  当然定义Block还是应该用copy(还有其他需要注意的地方,可以参考这篇文章:iOS: ARC和非ARC下使用Block属性的问题),因为非ARC下不copy的Block会在栈中,ARC中的Block都会在堆上的。

  可以这样复现问题。在非ARC环境下,定义一个简单类型,定义一个Block属性,先用正确的copy:

@interface TestCls : NSObject
@property (nonatomic, copy) void(^myBlock)();

@end

  在另一个类型里声明变量:

TestCls *_testObj

  然后在一个方法里,比如viewDidLoad中,设置Block变量,注意即便是在非ARC下,没有引用外部变量的Block类型也是NSGlobalBlock,而引用外部变量的Block才是NSStackBlock,如下代码

_testObj = [[TestCls alloc] init];

int outerVar = 12;
_testObj.myBlock = ^void()
{
    NSLog(@"Block被调用:%d", outerVar);
};
NSLog(@"Block类型:%@", [_testObj.myBlock class]);

  然后在另一个方法里(比如UIButton的点击事件方法里)去执行Block,如下:

_testObj.myBlock();

  测试环境是Xcode 6/iOS 7/8,如果最上面myBlock属性声明是copy或者strong的话,Block都会被copy,输出:

Block类型:__NSMallocBlock__
Block被调用:12

  如果上面myBlock属性声明是retain或者assign的话,Block表现起来就是assign,没有去copy,输出

Block类型:__NSStackBlock__

    

  此时可能会Crash(BAD_ACCESS),也有可能输出错误的值(我在控制台下测试会出现这种情况)。因为Block作用域在函数栈里,而函数已经执行完毕了。

总之,strong和retain竟然有不一样的地方,而声明Block属性请务必用copy。

Related posts:

iOS: 非ARC下返回Block
iOS: ARC和非ARC下使用Block属性的问题
iOS: NSData/NSMutableData的二进制数据读写
在线工具: 从Objective-C .m文件中提取函数定义
时间: 2024-12-24 06:12:43

iOS的属性声明:retain和strong的区别的相关文章

iOS中copy,retain,strong,assign,weak的区别以及使用

使用assign: 对基础数据类型 (NSInteger)和C数据类型(int, float, double, char,等)使用copy: 对NSString使用retain: 对其他NSObject和其子类 assign就是简单的赋值,不更改引用计数,所以直接使用基础数据 copy是直接拷贝内容,成为一个新的对象. retain释放旧的对象,将旧对象的值赋给新的对象,并使新的对象的引用计数加1 retain是指针拷贝 copy是分配新的内存属于内容拷贝,在拷贝之前都会释放旧的对象 在ARC中

iOS:不同属性声明方式的解析

代码: /* 属性声明方式说明: ----------------------- 1 @interface ... { id name } @end 这样声明的属性其实可以认为是private属性,因为它只能在方法里通过name引用,外部无法通过“object.name”的方式进行引用 (内部也不能通过self引用) ---------------------- 2 @interface ... @property id name @end 这样声明的属性可以认为是public属性,内部通过“s

retain、strong和copy测试

时不时会有点迷惑retain.strong.copy三者之间的区别,还是记录下来好一点,先看代码: 创建一个类,定义属性 #import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatomic, retain) NSString *strRetain; @property (nonatomic, strong) NSString *strStrong; @property (nonatomic, c

iOS开发知识点:理解assign,copy,retain变strong

一..h和.m文件的变化说明 1.对于.h头文件,主要是将属性定义由retain变为strong [java] view plaincopy @property (retain, nonatomic) 变为 [java] view plaincopy @property (strong, nonatomic) 2.在ARC之前,我们经常在.m中使用分类拓展来增加私有的property [java] view plaincopy @interface MJViewController () @pr

ARC声明属性关键字详解(strong,weak,unsafe_unretained,copy)

ARC声明属性关键字详解(strong,weak,unsafe_unretained,copy) 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都很熟悉了,在此我也不介绍,网上有很多相关文章. 但是在iOS 5中加入ARC,产生了几个新的关键字strong, weak, unsafe_unretained.  我们可以将其与以前的关键字对应学习: strong与retain类似,weak和unsafe_unretained这两个新关键字与assign类

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

iOS中属性 (nonatomic, copy, strong, weak)的使用 By hL

以下内容来自Stackflow的详解 1.Nonatomicnonatomic is used for multi threading purposes. If we have set the nonatomic attribute at the time of declaration, then any other thread wanting access to that object can access it and give results in respect to multi-th

iOS中assign,copy,retain之间的区别以及weak和strong的区别

@property (nonatomic, assign) NSString *title; 什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Reference Counting). copy: 建立一个索引计数为1的对象,然后释放旧对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 weak 和strong的区别: (weak和strong)不同的是 当一个对象不再有strong类型的指针指向它的时候 它会

对于atomic nonatomic assign retain copy strong weak的简单理解

atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作 1)atomic 设置成员变量的@property属性时,atomic是默认值,提供多线程安全 在多线程环境下,原子操作是必要的,否则有可能引起错误的结果.加了atomic后setter函数会变成下面这样: {lock} if (property != newValue) { [property release]; property = [newValue retain]; } {unlock} 2)n