Block 循环引用浅谈
来源:互联网 发布:php源码测试软件 编辑:程序博客网 时间:2024/06/06 03:33
Block 的循环引用问题,想必使用过 Block,几乎都遇到过。今天CodeReview时,发现还存在循环引用的问题。故简单记录如下:
一、循环引用的原因
简单来说就是,【互相持有,造成内存不释放】。
如: self --持有--> block --持有--> self 形成了一个环,中间还可能穿插其他对象,反正最后形成了一个闭环,造成谁也不撒手,故内存永远不释放。
二、解决方案
也是一句话,砍掉任一一个链,破坏这个互相持有的闭环。
1、self 不持有 block
void (^testBlock)() = ^(){ self.testStr = @"Hello block"; }; testBlock(@"");
2、block 不强持有 self : weakSelf & strongSelf
__weak __typeof__(self) weakSelf = self;__strong typeof(weakSelf) strongSelf = weakSelf;
即 Block 里对 self 为弱引用,不持有 self,即 self 的引用计数不会+1.
若仅引用一次,用weakSelf ,多次引用,则用 strongSelf 。strongSelf 是为了保证在 block 执行过程中,self 不会再变化。
至于二者区别,可以随便网上查一下,有很多人都对此进行了分享。
__weak __typeof__(self) weakSelf = self; self.block = ^(){ __strong typeof(weakSelf) strongSelf = weakSelf; testStr0 = @"这是 test 字符串"; NSLog(@"%@",strongSelf->testStr0); }; self.block();另,在 block 中对 self 的引用情况,包括使用 self 的属性,调用 self 的方法,以及使用 self 的成员变量。
__weak __typeof__(self) weakSelf = self; self.block = ^(){ __strong typeof(weakSelf) strongSelf = weakSelf; strongSelf->p_testStr = @"这是成员变量"; NSLog(@"%@",strongSelf->p_testStr); }; self.block();
3、block 执行完后,置为 nil
self.testStr = @"Test Str"; self.block = ^(){ NSLog(@"%@",self.testStr); }; self.block(); self.block = nil;
三、扩展
在总结循环引用的问题时,突发奇想这样一种情况:
若 block 中,有用了 GCD , GCD 的 block 里又用到了 self ,那该如何判断是否存在循环引用呢?
如:
void (^testBlock)() = ^(){ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5. * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.testStr = @"Hello block"; NSLog(@"%@>>>gcd执行了",self.testStr); }); }; testBlock(@"");再如:
self.block = ^(){ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5. * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.testStr = @"Hello block"; NSLog(@"%@>>>gcd执行了",self.testStr); }); }; self.block();其实,分析其持有关系,看有没有形成互相持有的环,若存在环,那肯定就循环引用了。
1、testBlock --持有--> GCD --持有--> self 【没有形成环,不存在循环引用】
2、self--持有--> block --持有--> GCD --持有--> self 【形成了环,故存在循环引用】
解决循环引用的方式还是如上面所述的三点即可。
附上 demo ,演示上文中提到的 block 中解决循环引用的方式。
阅读全文
0 0
- Block 循环引用浅谈
- 详解Block: block循环引用
- Block的循环引用
- block循环引用
- Block的循环引用
- block 防止循环引用
- block循环引用问题
- 循环引用的block
- block的循环引用
- block循环引用
- block循环引用问题
- block循环引用
- Block的循环引用
- Block的循环引用
- block循环引用问题
- BLOCK循环引用
- block的循环引用
- block的循环引用
- websocket(聊天功能)
- NYOJ 39
- Sky number
- Security-OAuth2.0 密码模式客户端实现(IDEA+springboot+maven)
- 关键字 assert
- Block 循环引用浅谈
- yolo配置文件的参数说明和reorg层的理解!
- 国内有什么好的集群调度系统吗?
- Hibernate中Criteria的完整用法
- 建造者模式
- C++中的istringstream 的用法
- Unable to import Maven project into IntelliJ IDEA2017
- flume netcat source 监听 44444 -记flume官方文档的简单例子
- C