AFNetworking内存泄漏详解

AFNetworking内存泄漏
好记性不如烂笔头,这个问题很久以前看过一次,后来碰到又忘记了。so写下来。

这里还是运用xcode自带的leaks来观察这个问题。
为了排除其他代码干扰,新建一个工程,导入afn代码。

一、空项目运行

首先空项目不进行任何代码编辑运行leaks。




运行结果很ok

二、加上AFN代码运行

- (void)viewDidLoad {
    [super viewDidLoad];
    
     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
     manager.requestSerializer.timeoutInterval = 20;
     manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [manager GET:@"https://www.baidu.com" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    }];
}

三、看代码

已经出现了内存泄漏,根据leaks提供的内容,可以看出来是delegate出现了循环引用。找到代码位置查看代码。


image.png

红色方框代码出现了leaks中的两个类,并且执行了设置delegate代码。继续进入NSURLSession方法查看。



此处的delegate并不是一个弱引用所以出现了循环引用。所以我们找的内存泄漏其实是NSURLSession的一个内存泄漏

四、解决方案

查阅资料主要由两种解决方案
1.将AFN只创建一个当做单例来使用,这样就避免了多次创建
2.苹果本身也是给出了解决方案的


image.png

通过finishTasksAndInvalidate方法将session设置成无效的

- (void)viewDidLoad {
    [super viewDidLoad];
    
     AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
     manager.requestSerializer.timeoutInterval = 20;
     manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [manager GET:@"https://www.baidu.com" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        [manager.session finishTasksAndInvalidate];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    }];
}

你可能感兴趣的:(AFNetworking内存泄漏详解)