欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

IOS内存泄漏检查方法及重写MLeakFinder

程序员文章站 2022-03-02 11:52:48
对于ios开发来讲,内存泄漏的问题,已经是老生常谈的话题。在日常的面试中经常会提到这些问题。我们日常的开发过程中进行内存泄漏的检测,一般是使用instrument工具中的leaks/allocatio...

对于ios开发来讲,内存泄漏的问题,已经是老生常谈的话题。在日常的面试中经常会提到这些问题。我们日常的开发过程中进行内存泄漏的检测,一般是使用instrument工具中的leaks/allocation来进行排查,网络上也有比较高效又好用的内存泄漏检测工具,mleakfinder。

mleakfinder-原理

首先看uiviewcontroller,当一个uiviewcontroller被pop或dismiss的时候,这个vc包括在这个vc上的view,或者子view都会很快的被释放。所以我们我们需要在uiviewcontroller被pop或dismiss后一小段时间后,在这个vc上的view,subview等是否还存在。

在uiviewcontroller+memoryleak.h的load方法中可以看到,早+load方法中通过runtime交换了viewwillappear,viewdidappear,dismissviewcontrolleranimated:completion:这三个方法。

1,首先看viewwillappear

当vc进来的时候,添加关联对象,并标记为no

2,在看viewdidappear

通过代码可以看出,获取当前关联对象的标记,当标记为yes的时候,就会调用willdealloc。

3,我们看什么时候会被标记为yes呢?

在uinavigationcontroller+memoryleak.h的popviewcontrolleranimated:方法中我们可以看到

我们可以看出,在vc被pop或者左滑返回的时候,相当于视图销毁,就会被标记为yes。

4,我们重点看willdealloc

1.第一步:我们可以看到,会先判断当前的class是否在白名单中,是的话就会return no,即不是内存泄漏的。
同时我们查看构建白名单的源码:使用了一个单例实现,确保只有一个,是个私有方法

同时在还支持,自定义的添加白名单

2. 第二步:判断该对象是否是上一次发送action的对象,是的话,不进行内存检测

3,第三步:弱指针指向self,2s延迟,然后通过这个弱指针调用-assertnotdealloc,若被释放,给nil发消息直接返回,不触发-assertnotdealloc方法,认为已经释放;如果它没有被释放(泄漏了),-assertnotdealloc就会被调用

5,现在我们回到:2的代码 [self willdealloc]

看一下他的源码

1,第一步:会通过 super调用父类的willdealloc,即上面目录4

2,第二步:调用willreleasechildren,willreleasechild遍历该对象的子对象,看其是否释放

通过代码可以看出,通过调用willreleasechildren的方法,获取当前对象viewstack,parentptrs,并且遍历children,为每个子对象设置viewstack,parentptrs,然后调用willdealloc。

通过源码看一下viewstask,parentptrs的实现

viewstack使用数组,parentptrs使用的集合形式。都是通过运行时,用关联对象添加属性。

parentptrs会在-assertnotdealloc中,会判断当前对象是否与父节点集合有交集。下面仔细看下-assertnotdealloc方法

1,第一步我们看到,通过parentptrs的判断是否有交集

产看其源码:

可以看到,创建了一个单例对象,通过集合的形式,判断是否有交集,是的话return。否则就进入第二步

2,第二步:addleakedobject

第一步:构造mleakedobjectproxy对象,给传入的泄漏对象 object 关联一个代理即 proxy

第二步:通过objc_setassociatedobject(object, kleakedobjectproxykey, proxy, objc_association_retain)方法,object强持有proxy, proxy若持有object,如果object释放,proxy也会释放

第三步:存储 proxy.objectptr(实际是对象地址)到集合 leakedobjectptrs 里边

第四步:弹框 alertview若 _internal_mlf_rc_enabled == 1,则弹框会增加检测循环引用的选项;若 _internal_mlf_rc_enabled == 0,则仅展示堆栈信息。

对于mleakedobjectproxy类而言,是检测到内存泄漏才产生的,作为泄漏对象的属性存在的,如果泄漏的对象被释放,那么mleakedobjectproxy也会被释放,则调用-dealloc函数

集合leakedobjectptrs中移除该对象地址,同时再次弹窗,提示该对象已经释放了

6,自己也在尝试重写该框架,欢迎大家一起交流

以上就是ios内存泄漏检查方法及重写mleakfinder的详细内容,更多关于ios内存泄漏的资料请关注其它相关文章!