美文网首页ios相关文章
AFNetworking非单例内存泄露

AFNetworking非单例内存泄露

作者: tangbin583085 | 来源:发表于2017-12-02 10:55 被阅读59次

    相信绝大部分的人都在使用AFNetworking框架,但却不知道如果使用不当,会造成内存泄露(我仅对3.0版本以上描述)。网上很多人都描述AFN会内存泄露,解决的方案就是使用单例,但是基本都没说为什么会发生内存泄露。

    使用非单例创建manager,但不销毁

    1,有些项目中会为每一个controller创建一个AFHTTPSessionManager来管理网络请求,但是!但是!如果没有在适当的位置执行invalidateSessionCancelingTasks
    比如:

    - (void)dealloc {
        [self.manager invalidateSessionCancelingTasks:YES];
    }
    

    最后就算你的controller已经销毁了,但是manager 对象还没有销毁,你可以验证一下。

    2,还有些项目自己封装了AFNetworking工具类,然后每次请求都会创建一个新的manager去请求数据,由于manager是局部变量,错误以为执行task之后,系统就会销毁manager,但是结果是manager不会销毁!
    以上的2中情况我都实验了并且利用苹果的内存检查工具,截了图:


    AFN内存泄露.png

    原因:

    因为AFNetworking是对苹果NSURLSession的封装,而NSURLSession的代理delegate是强引用了。当AFHTTPSessionManager(继承AFURLSessionManager)创建manager的时候,manager会引用session,而session的delegate又强引用了manager,所以就会造成循环引用,无法释放。 WX20171123-163547@2x.png
    苹果的官方文档也说得很清楚了!

    解决:
    一般情况下都使用单例了管理manager即可,如果真要使用非单例,那请注意在适当的位置调用

    [self.manager invalidateSessionCancelingTasks:YES];
    

    AFNetWorking给出的官方demo也是单例访问。(网络说单例的session可以减少TCP三次的握手)
    单例之后无出现内存泄露的红叉


    AFN单例解决内存谢落.png

    补充:AFN的completionHandler block在主线程执行且无引用

    大神已经帮我们在返回的结果主动调回了主线程,但progress block则在子线程执行。而且不用再在里面使用weakSelf了,因为block在代理AFURLSessionManagerTaskDelegate执行,执行完就移除了,所以也不用担心block引用的问题。

    如有说错,敬请指正。

    相关文章

      网友评论

        本文标题:AFNetworking非单例内存泄露

        本文链接:https://www.haomeiwen.com/subject/mflxbxtx.html