URLSession
1,随便说一下URLSession,这个类比之前的URLConnection下载数据或者文件,特别是大文件,App的内存和性能提升很多,不会急剧暴增。
URLSession的构造方法
//单例
@property (class, readonly, strong) NSURLSession *sharedSession;
//便利构造器
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
接下来的一句话非常重要!!
URLSession所有的网络都是Session发起的。而且所有的任务默认是挂起的,需要调用resume。
先记住这句话,等下会说到。
2,使用单例Session
self.session = [NSURLSession sharedSession];
[[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}] resume];
-
你会发现这个方法,没办法设置
delegate,就是你只能用Block回调。
这是因为单例构造的Session是系统全局的。设置delegate会出现你意想不到的事情,比A-App和B-App,两个App同时对单例设置了delegate,delegate是一对一映射,那么可能A-App的数据可能会返还给B-App。 -
这个可能很多文章都有提到过
[[[NSURLSession sharedSession] downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@",location);
}] resume];
Session的下载文件会暂存到沙盒路径的tmp里面,所以如果下载完成我们不主动去写入别的Path,那么文件很可能就消失了,系统会自动回收这块区域。
3,如果你使用便利构造器方法
NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
- 这里
delegateQueue可以设置nil,默认就是异步队列 - 要注意
Session对delegate是强引用,要手动Cancle或者Finish。
-(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;
}
不然dealloc不会调用的。
4,Session的断点续传
- (IBAction)pause:(id)sender {
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
//resumeData : 已下载的数据
self.resumeData = resumeData;
//释放下载任务
self.downloadTask = nil;
}];
}
- (IBAction)resume:(id)sender {
//没有续传任务
if (self.resumeData == nil) {
return;
}
//续传任务
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
//清空续传数据
self.resumeData = nil;
//所有的任务都是默认挂起的!!
[self.downloadTask resume];
}











网友评论