iOS的属性声明:retain和strong的区别
2016-05-25 13:15
288 查看
声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong)。不过在声明Block时,使用strong和retain会有截然不同的效果。strong会等于copy,而retain竟然等于assign!
当然定义Block还是应该用copy(还有其他需要注意的地方,可以参考这篇文章:iOS: ARC和非ARC下使用Block属性的问题),因为非ARC下不copy的Block会在栈中,ARC中的Block都会在堆上的。
可以这样复现问题。在非ARC环境下,定义一个简单类型,定义一个Block属性,先用正确的copy:
在另一个类型里声明变量:
然后在一个方法里,比如viewDidLoad中,设置Block变量,注意即便是在非ARC下,没有引用外部变量的Block类型也是NSGlobalBlock,而引用外部变量的Block才是NSStackBlock,如下代码
然后在另一个方法里(比如UIButton的点击事件方法里)去执行Block,如下:
测试环境是Xcode 6/iOS 7/8,如果最上面myBlock属性声明是copy或者strong的话,Block都会被copy,输出:
如果上面myBlock属性声明是retain或者assign的话,Block表现起来就是assign,没有去copy,输出
此时可能会Crash(BAD_ACCESS),也有可能输出错误的值(我在控制台下测试会出现这种情况)。因为Block作用域在函数栈里,而函数已经执行完毕了。
总之,strong和retain竟然有不一样的地方,而声明Block属性请务必用copy。
Related posts:
当然定义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文件中提取函数定义
相关文章推荐
- iOS scrollView嵌套scrollView滑动到顶部须松手解决
- 比较好的iOS博客文章
- 在Xcode中使用Git进行源码版本控制
- iOS源文件转cpp
- iOS开发——获取本设备IP
- iOS上线流程
- IOS链接报错问题- Duplicate Symbol链接错的原因总结和解决方法
- Ios9-Multitasking-多任务处理一(悬浮视频)
- iOS 保存图片到相册, 保存到指定的路径
- iOS 如何更改Cell中默认accessoryView的位置
- iOS学习之——学习中遇到的一些常用的方法及一些注意事项(持续更新)
- ios合并静态库
- IOS(CGGeometry)几何类方法总结
- xib自定义控件 在 6p上被放大的文头解决方案
- iOS9提示框的正确使用方式
- 导航控制器(NavigationController)的生命周期
- Xamarin 从原生IOS Native Library SDK创建Xamarin版本的C# SDK Bindings
- iOS button加边框设置圆角
- iOS图片实现可拉伸不变形的处理操作
- ios按钮点击导致程序崩溃