iOS闭包循环引用精讲
2016-03-02 16:00
316 查看
前言
本篇文章精讲iOS开发中使用Block时一定要注意内存管理问题,很容易造成循环引用。本篇文章的目标是帮助大家快速掌握使用block的技巧。我相信大家都觉得使用block给开发带来了多大的便利,但是有很多开发者对block内存管理掌握得不够好,导致经常出现循环引用的问题。对于新手来说,出现循环引用时,是很难去查找的,因此通过Leaks不一定能检测出来,更重要的还是要靠自己的分析来推断出来。
声景一:Controller之间block传值
现在,我们声明两个控制器类,一个叫ViewController,另一个叫HYBAController。其中,ViewController有一个按钮,点击时会push到HYBAController下。先看HYBAController:
![](http://www.henishuo.com/wp-content/uploads/2016/02/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2016-02-18-%E4%B8%8B%E5%8D%889.07.32.png)
可以简单说,这里形成了两个环:
ViewController->强引用了属性vc->强引用了callback->强引用了ViewController
ViewController->强引用了属性vc->强引用了callback->强引用了ViewController的属性button
对于此这问题,我们要解决内存循环引用问题,可以这么解:
不声明vc属性或者将vc属性声明为weak引用的类型,在callback回调处,将self.button改成weakSelf.button,也就是让callback这个block对viewcontroller改成弱引用。如就是改成如下,内存就可以正常释放了:
针对这种场景,给大家提点建议:
在控制器的生命周期viewDidAppear里打印日志:
场景二:Controller与View之间Block传值
我们先定义一个view,用于与Controller交互。当点击view的按钮时,就会通过block回调给controller,也就反馈到控制器了,并将对应的数据传给控制器以记录:分析:如下图所示:
![](http://www.henishuo.com/wp-content/uploads/2016/02/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7-2016-02-18-%E4%B8%8B%E5%8D%889.48.41.png)
所形成的环有:
vc->aView->block->vc(self)
vc->aView->block->vc.currentModel
解决的办法可以是:在创建aView时,block内对currentModel的引用改成弱引用:
模拟循环引用
假设下面如此写代码,是否出现内存得不到释放问题?(其中,controller属性都是强引用声明的)@autoreleasepool { A *aVC = [[A alloc] init]; B *bVC = [[B allcok] init]; aVC.controller = bVC; bVC.controller = aVC; }
分析:
aVC->强引用了bVC->强引用了aVC,因此形成了一个环,导致内存得不到释放。
写在最后
本篇文章就讲这么多吧,写本篇文章的目的是教大家如何分析内存是否形成环,只要懂得了如何去分析内存是否循环引用了,那么在开发时一定会特别注意内存管理问题,而且查找内存相关的问题的bug时,也比较轻松。源代码
本篇写了个小demo来测试的,如果只看文章不是很明白的话,如果下载demo来运行看一看,可以帮助您加深对block内存引用问题的理解。下载地址:标哥的GITHUB下载地址
问啊-定制化IT教育平台,牛人一对一服务,有问必答,开发编程社交头条 官方网站:www.wenaaa.com
QQ群290551701 聚集很多互联网精英,技术总监,架构师,项目经理!开源技术研究,欢迎业内人士,大牛及新手有志于从事IT行业人员进入!
相关文章推荐
- iOS9上实现3D Touch功能之快速启动
- iOS- 指压即达,如何集成iOS9里的3D Touch
- iOS中属性的声明
- Cordova 系列之创建一个iOS项目
- iOS中的__block 与__weak
- 关于iOS多线程,你看我就够了
- iOS、mac开源项目及库汇总
- ios vlc
- 用CocoaPods做iOS程序的依赖管理
- iOS-银行卡四位数分隔效果
- iOS 各种控件默认高度(图示)
- iOS利用系统打电话和发短信
- FFmpeg解析视频保存为yuv
- iOS 代理为啥要用weak修饰? (刨根问底一)
- iOS播放系统声音
- 最简单的iOS真机抓包方式
- iOS SDWebImage使用详解
- IOS--GCD基础
- iOS 函数调用的流程
- iOS中设置导航栏标题( titleView)的字体颜色和大小