block 什么时候需要构造循环引用
2016-12-15 16:46
302 查看
需要不使用 weak self 的场景是:你需要构造一个循环引用,以便保证引用双方都存在。比如你有一个后台的任务,希望任务执行完后,通知另外一个实例。在我们开源的 YTKNetwork 网络库的源码中,就有这样的场景。
在 YTKNetwork 库中,我们的每一个网络请求 API 会持有回调的 block,回调的 block 会持有 self,而如果 self 也持有网络请求 API 的话,我们就构造了一个循环引用。虽然我们构造出了循环引用,但是因为在网络请求结束时,网络请求 API 会主动释放对 block 的持有,因此,整个循环链条被解开,循环引用就被打破了,所以不会有内存泄漏问题。代码其实很简单,如下所示:
总结来说,解决循环引用问题主要有两个办法:
第一个办法是「事前避免」,我们在会产生循环引用的地方使用 weak 弱引用,以避免产生循环引用。
第二个办法是「事后补救」,我们明确知道会存在循环引用,但是我们在合理的位置主动断开环中的一个引用,使得对象得以回收。
在 YTKNetwork 库中,我们的每一个网络请求 API 会持有回调的 block,回调的 block 会持有 self,而如果 self 也持有网络请求 API 的话,我们就构造了一个循环引用。虽然我们构造出了循环引用,但是因为在网络请求结束时,网络请求 API 会主动释放对 block 的持有,因此,整个循环链条被解开,循环引用就被打破了,所以不会有内存泄漏问题。代码其实很简单,如下所示:
// YTKBaseRequest.m - (void)clearCompletionBlock { // nil out to break the retain cycle. self.successCompletionBlock = nil; self.failureCompletionBlock = nil; }
总结来说,解决循环引用问题主要有两个办法:
第一个办法是「事前避免」,我们在会产生循环引用的地方使用 weak 弱引用,以避免产生循环引用。
第二个办法是「事后补救」,我们明确知道会存在循环引用,但是我们在合理的位置主动断开环中的一个引用,使得对象得以回收。
相关文章推荐
- LeetCode #226 - Invert Binary Tree - Easy
- spring annotation 注入static 属性
- JAVA远程连接linux服务器读取文件(JSch)
- MySql中利用insert into select 准备数据uuid主键冲突
- 利用Application 存储全变量
- springboot CGLib 方式实现AOP代理问题
- [kpw] Kindle Paperwhite被强制升级到5.6.5后,USBNetwork无法使用
- OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)
- ORACLE中STATUS为INACTIVE但是SERVER为SHARED状态的会话浅析
- grep
- 第五章 引用类型 Function 类型
- 在css嵌套中的html的table里的字左右不对齐
- iOS之应用程序国际化
- lintcode,排序列表转换为二分查找树
- PHP SOCKET编程
- Spring框架下类的初始化顺序
- ZDOCUMENT_BILL_EXCHANG_POST
- windows下mongodb的启动以及设置成系统服务
- java 查找字符串所在的位置
- JZOJ 4762 千帆渡(动态规划)