- 一般来说,在ARC下修饰delegate要用weak而不是strong
用tableview的代理(viewcontroller)例子来解释:
如果tableview用strong强引用了其代理viewcontroller,viewcontroller又strong强引用了tableview,就造成了循环引用,谁都不能被释放,会造成内存泄漏。用weak使tableview弱引用viewcontroller,不会造成循环引用。
- 而对于NSURLSession来说却比较特殊,下面是苹果API里面的说明
The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you do not invalidate the session by calling the invalidateAndCancel or finishTasksAndInvalidatemethod, your app leaks memory until it exits.
可以看出NSURLSession对代理是强引用,如果不正确处理的的话,就会造成内存泄漏。
那么我们怎么做才能防止内存泄漏的发生呢,苹果给我们提供了两个方法,invalidateAndCancel or finishTasksAndInvalidate
- 一个是完成任务后将session给干掉,在NSURLSessionDownloadDelegate 代理方法中
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSLog(@"完成 %@",location);
//完成任务,
[self.session finishTasksAndInvalidate];
//清空Session
self.session = nil;
}
- 一个是在控制器返回时,任务不再下载了
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
//取消会话
[self.session invalidateAndCancel];
self.session = nil;
}
怎么做看自己的选择了,苹果这样做也是有原因的
- 在我们平常的网络开发中,网络访问操作,封装到一个方法中,由一个统一的单例对象来负责所有的网络事件,比如常用的AFN
- Session对代理(单例)进行强引用,单例本身就是一个静态的实例,本身就不需要释放
补充
- 下载的文件在哪里
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSLog(@"完成 %@",location);
}
如果在回调方法中,不做任何处理,下载的文件会被删除
通过location找到文件夹位置,运行程序的时候可以看到下载文件其实是放在temp里面的,但下载完后系统会自动回收这块区域。
*设计的目的是什么?
- 通常从网络上下载文件,zip 文件最多,替用户节约流量
- 如果是 zip 包,下载之后,需要解压
- 解压之后,原始的 zip 文件就不需要了,系统会自动帮我们删除
- dataTask 和 downloadTask 下载对比
- NSURLSessionDataTask
下载文件可以实现离线断点下载,但是代码相对复杂 - NSURLSessionDownloadTask
下载文件可以实现断点下载,但不能离线断点下载
内部已经完成了边接收数据边写入沙盒的操作
解决了下载大文件时的内存飙升问题