- 定义全局的session属性
@interface ViewController () <NSURLSessionDownloadDelegate>
/// 自定义session实现文件下载
@property (nonatomic,strong) NSURLSession *downloadSession;
@end
- 懒加载中自定义文件下载的session,并设置代理
- (NSURLSession *)downloadSession
{
if (_downloadSession == nil) {
// 设置session的配置信息
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
// 解除循环引用 : 无效的方式
// __weak typeof(self) weakSelf = self;
// 自定义session并设置代理,实现文件下载
_downloadSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
}
return _downloadSession;
}
问题分析
循环引用测试
- 添加导航控制器,实现
dealloc
方法,测试控制器是否能够销毁
- (void)dealloc
{
NSLog(@"%s",__FUNCTION__);
}
测试结果 : 当有下载任务时,控制器无法销毁.
解决办法
- 文档说明
- 解除循环引用的问题
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// 在控制器即将销毁时,将sessio立即置为无效
[self.downloadSession invalidateAndCancel];
// 在控制器即将销毁时,当下载任务执行结束之后再把session置为无效
// [self.downloadSession finishTasksAndInvalidate];
}
NSURLSession注意事项
一旦指定了 session 的代理,session会对代理进行强引用,如果不主动取消 session,会造成内存泄漏!
解决方案
- 解决方法1:在任务完成后取消
session
- 缺点:
session
一旦被取消就无法再次使用. - 解决方法2:在视图将要消失的时候取消
session
- 优点:只需要一个全局的
session
统一管理.