AFN的内存泄漏问题

在使用instruments作内存泄漏分析时,发现全部使用以下语句的地方都有内存泄漏,OMG:安全

leaks上图: bash

if (!_manager) {
    _manager = [AFHTTPSessionManager manager];
}
复制代码

缘由:session在ARC下不会及时释放网络

我所用到的网络请求不是很复杂,不想再新建类去写单例了,就把单例放在了AppDelegate中,用到的时候在经过AppDelegate拿。由于须要用到AFURLSessionManager,因此就写一个单例方法。session

static AFHTTPSessionManager *manager ;`
-(AFHTTPSessionManager *)sharedHTTPSession{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [AFHTTPSessionManager manager];
        manager.requestSerializer.timeoutInterval = 10;
    });
    return manager;
}
复制代码

可是 作成单例并非很好的方式,能够在AFAppDotNetAPIClient中的dealloc中手动触发sessionManager.session.finish...()释放session的delegete,打破AF内部的循环引用ui

完美解决 @·@
缘由探究: AFURLSessionManager实现了NSURLSession的协议,即AFURLSessionManagerNSURLSession互相持有,若是这个delegate是week的话,那没什么问题,可是系统提供的是retain:如图spa

NSURLSession

因此里面是有循环引用的。一旦使用非单例的方式来使用AFHTTPSessionManager,若是不作特殊处理,就会致使这个对象在应用存活期间是不会销毁的,若是应用网络请求过多,用户反复进入各类vc,内存泄漏明显。这明显不安全。code

好在AFN和NSURLSession都有方法能够解决:cdn

//废弃session对象。cancelPendingTasks决定是否取消此session中的tasks
–(void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks 
复制代码

方法二:对象

__weak typeof(manager) weak_manager = manager;
    [manager requestWithMethod:method
        URLString:uri
        parameters:param
        success:^(NSURLSessionDataTask *task, id responseObject) {
            if (completion) {
                completion(YES, responseObject, task.response);
            }
            [weak_manager invalidateSessionCancelingTasks:YES];
        }
        failure:^(NSURLSessionDataTask *task, NSError *error) {
            if (completion) {
                completion(NO, error, task.response);
            }
            [weak_manager invalidateSessionCancelingTasks:YES];
        }];
复制代码
相关文章
相关标签/搜索