美文网首页
AFNetworking 3.0 中的内存泄露

AFNetworking 3.0 中的内存泄露

作者: 芙箩娅 | 来源:发表于2016-08-26 19:07 被阅读2351次

    前言

    打开项目代码,使用leak检测内存泄露的时候被吓坏了(忘了截图了……),满屏幕的红X,101 new leaks 35new leaks 28new leaks ,心想计算是block发生了循环引用也应该不至于这么崩才对吧!

    勾选call tree中的 转化call tree 和隐藏系统类库 (2 + 3),定位发生内存泄露的地方,发现都是诸如 [self loadNewData] [self loadData]之类的地方,估计就是AFN出问题了。

    A53D969B-F57B-474D-8B34-05280AF5DF1B.png

    查询资料后果然如此……

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    

    使用自定义的NetTool时(即AFNetworking的二次封装),使用了这个manager作为实际的get post 的载体,但是,这个方法很像是一个单例,但确实不是单例,SVProgressHUD才是单例,这个不是,这只是一个类方法!

    // AFN中 manager的方法,真的不是单例……
    + (instancetype)manager {
        return [[[self class] alloc] initWithBaseURL:nil];
    }
    
    - (instancetype)initWithBaseURL:(NSURL *)url {
        return [self initWithBaseURL:url sessionConfiguration:nil];
    }
    
    

    因此,如果直接在中间件里面使用这个manager,每次网络请求的时候,都会实例化一个对象出来,后果自然是滚滚而来的泄露了。

    解决方法:

    把manager封装成一个单例即可,这样每次调用的时候就不会实例化了。(应该是这个思路吧……)

    // 在AppDelegate中塞入这样一个单例并暴露类方法,设置请求超时为10秒。
    static AFHTTPSessionManager *manager ;
    
    - (AFHTTPSessionManager *)sharedHTTPSession {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            manager = [AFHTTPSessionManager manager];
            manager.requestSerializer.timeoutInterval = 10;
        });
        return manager;
    }
    
    // 再在NetTool中使用这个方法来获取AFHTTPSessionManager 的单例
    /** 自定义GET请求 */
    + (void)afnGet:(NSString *)url params:(NSDictionary *)params success:(void(^)(id json))success failure:(void(^)(NSError *error))failure{
        AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        AFHTTPSessionManager *manager = [app sharedHTTPSession];
        manager.responseSerializer = [AFJSONResponseSerializer serializer];
        [manager GET:url parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (success) {
                success(responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure) {
                failure(error);
            }
        }];
    }
    

    这样使用NetTool做网络请求的时候就不会发生内存泄露了

    D4BB6968-744E-4A1E-84CC-B133E61AE54E.png 1.jpg

    头一次感觉看到绿色的这么爽!嗯……好像哪里不对!

    相关文章

      网友评论

          本文标题:AFNetworking 3.0 中的内存泄露

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