Objective-C 循环引用
2017-01-30 00:49
239 查看
前言
之前的博客内存管理中类与类的相互交叉引用使得我们手动管理内存并不是特别简单,在ARC下难道我们就一切都交给编译器吗,答案是否定在一些场景中开始需要我们(开发者)注意避免内存泄漏。今天来说说循环引用,在我们实际开发中是非常常见的,一不小心我们就调入坑里面了。循环引用
循环引用:就是相当于两个人相爱,你中有我,我中有你,都各自放不下对方,即时分手也是相互想着对方。这个比喻不知道是否形象,就是这样的道理下面我们图片展示循环引用。两个类A和B相互强引用对方,这样导致各自的retainCount +1 ,造成内存内存泄漏,那么我们如果有效的避免这种情况的发生呢?
如果我们把其中一个类不引用类就不会引起,这样就可以各自释放,但是在实际开发中这样情况还是比较常见的,我们引入weak(弱引用),这样我们使得两个相爱的人变为普通人。但是还是可以相互消息传递。如下图:
上图中只要有一个弱引用对象就不会引起循环应用,A中强引用B,B的retainCount +1,但是B弱引用A,A中的retainCount 并没有变化,所有如果A销毁那么对用retainCount -1 = 0 也就释放了。
那么在实际开发中我们在那么地方特别容易掉进这些坑里面,我们又该如何排查。
实际开发场景
场景一:类在使用delegate这使我们在开发中最常见的问题,声明delegate,一定要使用weak;
场景二:block内代码快中
经常我们使用block内要使用本类的属性,那么这个时候要注意了,改用weak就用weak不要偷懒。block内部中用到的对象进行强引用(ARC)或者retainCount增1(非ARC)。在实际开发中分析注意。在之后的博客中我们来介绍block的内部实现和特性。
场景三:计时器NSTimer
这个涉及到计时器NSTimer的正确使用,我们创建定时传入target为self,
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES]; - (void)cleanTimer { [_timer invalidate]; _timer = nil; }
我们正确使用定时器,如果有外部类调用本类的定时器,那么对定时器的管理如停止应该交给使用类,如果直接在本类销毁,但是外部调用者计时器还在一直运行,就产生相互等待形成循环应用。
PS
实际开发中这个问题大家都知道但是还是难免会出现这样的问题,因为一个页面中引用很多的类和方法,在使用的时候难免疏忽,在排查过程中发现在内存泄漏,都要认真仔细的分析原因和相互持有关系到底是什么原因引起的,调试的时候是在找不到哪里可以使用逐行注释的方式进行排查,在dealloc内打断点查看是否销毁。以上内容如果有错误的地方欢饮大家留言,我会及时更正,谢谢!相关文章推荐
- Objective-C中循环引用的问题 深入剖析实用版
- objective-c基础语法学习之--(6)内存管理经典问题:循环引用
- Objective-c - ARC机制下的循环引用
- objective c:循环引用
- Objective-c中block使用时的循环引用问题
- objective-c启用ARC时的内存管理 (循环引用)
- Objective-C 循环引用的处理
- Objective - C基础: 第五天 - 6.循环引用
- Objective-C—引用计数器、多个对象之间的内存管理、set方法的内存管理、@property参数、循环引用
- Objective-C内存管理第四弹:循环引用
- Objective-c 循环引用
- Objective - C基础: 第六天 - 3.ARC循环引用
- Objective-C:对象之间循环引用会造成死循环
- 【Objective-C高级编程】iOS与OS X多线程和内存管理(九) Block 循环引用
- Objective-C - 循环引用问题
- Objective-C基础学习笔记(八)-内存管理-autorelease使用-property创建对象的内存管理-循环引用的内管管理
- Objective-C(十五、内存管理,MRC,循环引用,dealloc和setter方法)——iOS开发基础
- 一个多线程死锁的问题,一个循环引用的问题
- block使用小结、在arc中使用block、如何防止循环引用
- block使用小结、在arc中使用block、如何防止循环引用