iOS block循环引用精讲
2016-04-12 22:28
543 查看
前言
本篇文章精讲iOS开发中使用Block时一定要注意内存管理问题,很容易造成循环引用。本篇文章的目标是帮助大家快速掌握使用block的技巧。我相信大家都觉得使用block给开发带来了多大的便利,但是有很多开发者对block内存管理掌握得不够好,导致经常出现循环引用的问题。对于新手来说,出现循环引用时,是很难去查找的,因此通过Leaks不一定能检测出来,更重要的还是要靠自己的分析来推断出来。
声景一:Controller之间block传值
现在,我们声明两个控制器类,一个叫ViewController,另一个叫HYBAController。其中,ViewController有一个按钮,点击时会push到HYBAController下。先看HYBAController:
可以简单说,这里形成了两个环:
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,也就反馈到控制器了,并将对应的数据传给控制器以记录:分析:如下图所示:
所形成的环有:
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时,也比较轻松。
相关文章推荐
- Ruby中Block和迭代器的使用讲解
- Ruby中使用Block、Proc、lambda实现闭包
- Ruby中的block、proc、lambda区别总结
- Lua的内存管理浅析
- 跟我学习JScript的Bug与内存管理
- 跟我学习javascript的垃圾回收机制与内存管理
- 深入探讨PHP中的内存管理问题
- linux 内存管理机制详细解析
- 解析PHP中的内存管理,PHP动态分配和释放内存
- javascript内存管理详细解析
- JavaScript内存管理介绍
- Cocos2d-x的内存管理总结
- 模拟实现C语言中的内存管理
- 如何消除inline-block属性带来的标签间间隙
- javascript错误的认识不用关心内存管理
- IOS中内存管理那些事
- Python深入学习之内存管理
- 全面解析Objective-C中的block代码块的使用
- 简单说说STL的内存管理
- InnoDB存储引擎的内存管理机制