前一段时间,在优化公司项目代码,采用Leak对项目进行了内存泄漏的检测。结果一片触目惊心的红,吓了我一跳。
668B912D-841B-47C6-AFC4-AC03BC527EC9.png仔细看了一下,大部分都是AFN导致的内存泄漏。
我觉得非常的震惊,AFN怎么可能会造成这么多的内存泄漏呢?后来查找了一下原因,原因其实是
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
一直以来,我都以为这句代码是返回一个单例对象,然后我点进去看了一下,返现并不是
3159C7E3-6078-4B38-B1D3-544EC623F9D0.png每次调用都会返回一个新创建的对象,而且这个对象被创建之后并不会被释放掉。方法调用顺序如下:
WX20170724-194842.png WX20170724-194956.png会调用父类的方法,进入父类的方法后,会发现父类强引用这一个NSURLSession对象
WX20170724-195228.png然后父类本身又成为了NSURLSession的代理
WX20170724-195407.png而当我们点进去NSURLSession的头文件会发现它的代理是用retain关键字修饰的
WX20170724-195742.png这就是为什么不能被释放的的原因。
既然找到了原因,那就好办了。我看了一下之前封装的网络工具类来获取AFHTTPSessionManager对象的时候并没有采用单例方法,因为之前以为AFN给我返回的就是一个单例对象。然后我就把之前的方法稍微改了一下,返回一个单例对象,再次检测的时候,内存泄漏就消失不见了。
顺带说一句,一点点的内存泄漏平常我们并不会感觉到有什么,但是当内存泄漏堆积到一定程度导致内存溢出,那就出大事啦。
网友评论