iOS Block及block的循环引用

大家对循环引用问题应该有很强的意识,所以我们一般的在使用block的时候特别注意循环引用,通常都是_ _weak. 

Masonry框架相信对于一个iOS开发者来说应该很熟悉吧,但是Masonry的mas_makeConstraints方法里的block却直接使用self,却不会引起循环引用,这是为什么呢?

首先要明白block产生循环引用的原因:

block任何时候都会强引用在block代码块内部的对象,block消失,则强引用消失,block一直留存,强引用一直在,所以问题的关键是block是否会消失,如果A对象直接或者间接强引用一个block,block正好又强引用对象,那么就产生的循环引用

masonry解决的办法是释放block.

其实这个block是个栈block,栈block有个特性就是它执行完毕之后就出栈,出栈了就会被释放掉。看mas_makexxx的方法实现会发现这个block很快就被调用了,完事儿就出栈销毁,构不成循环引用,所以可以直接放心的使用self。

拓展:block的种类

Objective-C 中 Block 有三种类型:

NSStackBlock存储于栈区

NSGlobalBlock存储于程序数据区

NSMallocBlock存储于堆区


NSGlobalBlock

block 内部没有引用外部变量的 Block 类型都是 NSGlobalBlock 类型,存储于全局数据区,由系统管理其内存,retain、copy、release操作都无效。

NSStackBlock

block 内部引用外部变量,retain、release 操作无效,存储于栈区,变量作用域结束时,其被系统自动释放销毁。支持copy,copy之后生成新的NSMallocBlock类型对象。

NSMallocBlock

如上例中的_block,[blockA copy]操作后变量类型变为 NSMallocBlock,支持retain、release,虽然 retainCount 始终是 1,但内存管理器中仍然会增加、减少计数,当引用计数为零的时候释放(可多次retain、release 操作验证)。copy之后不会生成新的对象,只是增加了一次引用,类似retain,尽量不要对Block使用retain操作

事例:

@property(nonatomic,copy)void(^block)();

intvalue =10;

void(^blockA)() = ^{

NSLog(@"value: %d",value);

 };

NSLog(@"ARC 引用计数: %ld, block is: %@",CFGetRetainCount(((__bridgeCFTypeRef)blockA)), blockA);

void(^blockB)() = ^{

NSLog(@"blockB")

; };

NSLog(@"ARC 引用计数: %ld, block is: %@",CFGetRetainCount(((__bridgeCFTypeRef)blockB)), blockB); 

 _block = blockA;

NSLog(@"ARC 引用计数: %ld, block is: %@",CFGetRetainCount(((__bridgeCFTypeRef)_block)), _block);

打印结果:

ARC 引用计数:1, blockis: <__NSMallocBlock__:0x6080000536b0> 

 ARC 引用计数:1, blockis: <__NSGlobalBlock__:0x106bc7140> 

 ARC 引用计数:1, blockis: <__NSMallocBlock__:0x6080000536b0>

block类型转换

intvalue =10;

NSLog(@"%@",^{

NSLog(@"value: %d",value);

 });

void(^blockA)() = ^{

NSLog(@"value: %d",value); 

 };

NSLog(@"ARC 引用计数: %ld, block is: %@",CFGetRetainCount(((__bridgeCFTypeRef)blockA)), blockA);

打印结果<__NSStackBlock__: 0x7fff592aebd8>

ARC 引用计数: 1, block is: <__NSMallocBlock__: 0x6180000487f0>

由此看出,block 变量在引用外部变量的时候系统自动将其拷贝到堆区了,造成我们看到变量 blockA 是 NSMallocBlock 类型

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Block基础和retain cycle(循环引用) blcok简介 Block 是c语言的扩展,并不是什么高新技...
    董军1990阅读 12,340评论 22 69
  • Block简介(copy一段) Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是...
    qui丶MyLove阅读 440评论 0 0
  • Block作为C语言的扩展,和其他语言的闭包或lambda表达式是一回事。Block不支持ARC,必须自己管理内存...
    AYuan_阅读 403评论 0 0
  • 下一年不稳定因素太多了,但现在还是要做好自己,真的是要尽快上岸啊!!!不能一直拖后腿啊!!!
    谢谢你过去和未来阅读 177评论 0 0
  • 放假了,很无聊。 小丫在楼上写作业,丫爸和我,还有晴儿,我们三个都在楼下看手机,手机是最亲密的爱人,谁也离不开。 ...
    艺味深藏阅读 3,873评论 68 125