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:post

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

@end

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

TestCls *_testObj

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

_testObj = [[TestCls alloc] init];

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

  而后在另外一个方法里(好比UIButton的点击事件方法里)去执行Block,以下:spa

_testObj.myBlock();

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

Block类型:__NSMallocBlock__
Block被调用:12

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

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文件中提取函数定义
相关文章
相关标签/搜索