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出现了循环引用。找到代码位置查看代码。
红色方框代码出现了leaks中的两个类,并且执行了设置delegate代码。继续进入NSURLSession方法查看。
此处的delegate并不是一个弱引用所以出现了循环引用。所以我们找的内存泄漏其实是NSURLSession的一个内存泄漏
四、解决方案
查阅资料主要由两种解决方案
1.将AFN只创建一个当做单例来使用,这样就避免了多次创建
2.苹果本身也是给出了解决方案的
通过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) {
}];
}