OC 循环引用

来源:互联网 发布:c语言怎么入门 编辑:程序博客网 时间:2024/06/07 09:16

ARC已经出来很久了,自动释放内存的确很方便,但是并非绝对安全绝对不会产生内存泄露。导致iOS对象无法按预期释放的一个无形杀手是——循环引用。循环引用可以简单理解为A引用了B,而B又引用了A,双方都同时保持对方的一个引用,导致任何时候引用计数都不为0,始终无法释放。若当前对象是一个ViewController,则在dismiss或者pop之后其dealloc无法被调用,在频繁的push或者present之后内存暴增,然后APP就duang地挂了。
防止循环引用导致的内存泄露,基本上有两种方法。
1)如果其中一个对象的生命周期覆盖另一个对象,则采用OBJC推荐的策略,短周期对象保持长周期对象使用assign。
2)如果相互引用的对象其生命周期不能覆盖对方,则必须在各自生命周期的终点处打断对方,打断代码不能依赖在dealloc时打断。比如对于UI对象可通过事件处打断,线程对象于Main结尾处打断。只要有一处打断被执行就不会产生内存泄露。
此外还有另一种解决方法——利用指针的指针建立依赖引用机制。
这里提供一下思路:引用双方只assign不retain,双方再额外存储对方引用的指针,当一方release时顺便将自身在对方的引用清空,以达到通知连接断开的目的。可将这种引用关系封装为一个类简化使用。
优点:避免循环引用导致内存泄露,即便在release处释放连接也不会引起内存泄露。
缺点:引用返回的是id类型,因此使用时需要类型转换。
另外编程时还要注意非预期的循环引用。比如OBJC库中经常使用字典作为参数的保存位置,而字典使用retain保存对象。如果A保持字典,字典中又保持A,或者保持B,但B保持A,则有可能产生内存泄露。
总之循环引用引起内存泄露,是需要在OBJC中额外注意的。C/C++不会产生此问题,因为引用需要手工维护。JAVA、C#中由于垃圾回收机制,也无需刻意注意。、
http://www.cnblogs.com/wengzilin/p/4347974.html

0 0