博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS的属性声明:retain和strong的区别
阅读量:6834 次
发布时间:2019-06-26

本文共 1238 字,大约阅读时间需要 4 分钟。

  声明属性时用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下返回BlockiOS: ARC和非ARC下使用Block属性的问题iOS: NSData/NSMutableData的二进制数据读写在线工具: 从Objective-C .m文件中提取函数定义

 

转载于:https://www.cnblogs.com/jw-blog/p/5526655.html

你可能感兴趣的文章
(转)S5PV210--1---210启动方式和代码前16字节
查看>>
Zlib与GZip - woaidongmao - C++博客
查看>>
ASP.NET那点不为人知的事(四)
查看>>
ExtJs 4.2 treePanel
查看>>
typeof和instanceof的区别
查看>>
Windows 7下面安装VMware、BackTrack5(BT5)、minidwep-gtk
查看>>
Java中获取键盘输入值的三种方法
查看>>
最少硬币问题(受限)NK1132
查看>>
ltrace查看库调用
查看>>
spring3.0事务配置及expression表达式介绍
查看>>
head设计模式 01
查看>>
PostgreSQL的神秘现象
查看>>
windows下安装redis
查看>>
使用doxygen生成中文pdf文档
查看>>
安全卫士分析--号码归属地
查看>>
常用计数器的verilog实现(binary、gray、one-hot、LFSR、环形、扭环形)
查看>>
CCS学习资料汇总
查看>>
WCF 中 TCP 与 HTTP 性能简单比较
查看>>
04 企业的结构
查看>>
FlipViewDemo
查看>>