NSURLSession,为iOS7中的新网络接口,是在2013年的WWDC上,由Apple提出的NSURLConnection继任者的:NSURLSession。通常来说,为了防止循环引用,代理都会使用weak或者assign参数,但NSURLSession的代理却用了retain:
@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
苹果为什么这么做?先看下session的构造方法:
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
调用这个方法的同时会初始化一个NSURLSession对象,并为其设置代理。关于代理,官方文档中如下描述:
The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you don’t invalidate the session, your app leaks memory until it exits.
意思是说:session对象会对delegate对象持有一个强引用, 需要手动调用session对象的invalidate方法, 否则会产生内存泄漏。
刚看到的时候有些疑惑,后来经过思考,慢慢想清楚一些,如果此处session不对代理进行强引用,假设:有一控制器A,在控制器A push 控制器B,控制器B开始下载任务,此时如果点击返回,那么正常情况下控制器B销毁,B中的代理方法也理所当然的无法执行,session对控制器的强引用也就是为了能够正常的进行后台下载的操作。
当然,如果希望在下载完成后正常释放控制器,那么需要在下载完成后调用以下方法即可。
- (void)invalidateAndCancel;