NSURLConnection 与 NSURLSession 区别
20 June 2016
NSURLConnection 与 NSURLSession 区别
NSURLSession 官方说法
NSURLSession
是iOS7后出来的替代NSURLConnection
的API;NSURLSession
通过绑定一个 delegate 在一个网络会话的生命周期里调用某些事件;NSURLSession
对象是线程安全的;NSURLSession
默认使用系统提供的delegate,并适当的使用现有的代码使用;NSURLSession
通过创建NSURLSessionTask
代表资源被加载的任务,类似NSURLConnection
对象,但相比有更多可控制和定制的 delegate 模型;NSURLSessionTask
对象创建后是处于挂起状态,只有发-resume
消息才会执行;NSURLSessionTask
的子类 在加载 Data 和 文件下载的使用上有所不同;NSURLSessionDataTask
接收到资源时会回调RLSession:dataTask:didReceiveData:
代理method;NSURLSessionUploadTask
与NSURLSessionDataTask
的构造方法不同,他需求显示的引用file或data object;NSURLSessionDownloadTask
会直接把response data写入到临时文件,网络会话结束后,delegate 会发送一个URLSession:downloadTask:didFinishDownloadingToURL:
消息来处理下载文件,如果中途取消则会生成一个Blob Data以便下次恢复下载;- 从iOS9开始,使用
NSURLSessionStream
可以通过一个给定的主机和端口直接建立TCP/IP连接;
NSURLSession的优点(参考:为什么要使用NSURLSession)
后台上传和下载:
只需在创建NSURLSession的时候配置一个选项,就能得到后台网络的所有好处;能够暂停和恢复网络操作:
使用NSURLSession API能够暂停,停止,恢复所有的网络任务,再也完全不需要子类化NSOperation;可配置的容器:
对于NSURLSession里面的requests来说,每个NSURLSession都是可配置的容器。举个例来说,假如你需要设置HTTP header选项,你只用做一次,session里面的每个request就会有同样的配置。提高认证处理:
认证是在一个指定的连接基础上完成的。在使用NSURLConnection时,如果发出一个访问,会返回一个任意的request。此时,你就不能确切的知道哪个request收到了访问。而在NSURLSession中,就能用代理处理认证。丰富的代理模式:
在处理认证的时候,NSURLConnection有一些基于异步的block方法,但是它的代理方法就不能处理认证,不管请求是成功或是失败。在NSURLSession中,可以混合使用代理和block方法处理认证。
NSURLSession 简单使用
NSURLSession *session = [NSURLSession sharedSession];
[[session dataTaskWithURL:[NSURL URLWithString:londonWeatherUrl]
completionHandler:^(NSData *data,
NSURLResponse *response,
NSError *error) {
// handle response
}] resume];
NSURLSession 相关的类体系
参考: NSURLSession的基本使用 使用NSURLSession
NSURLConnection 官方说法
NSURLConnection
本身对网络会话可用操作很少,仅提供了对异步加载 URL request 启动和取消操作;- 利用
NSURLConnectionDataDelegate
协议,NSURLConnection
可以把资源数据直接加载到内存;使用NSURLConnectionDownloadDelegate
协议,NSURLConnection
可以把资源数据加载到文件;这两个协议都是NSURLConnectionDelegate
子协议; - 网络请求结束后,若失败会向delegate发送
connection:didFailWithError:
消息,若成功或下载成功则会发送connectiondidFinishLoading:
或connectionDidFinishDownloading
消息; - 发送一个
-cancel
消息会取消当前的网络加载器,但是不能保证其delegate的消息不被继续传递,所以这里要注意当取消了网络加载后其delegate释放后的问题; - 当Connection被建立后,
NSURLConnection
会执行一个对NSURLRequest
的深拷贝,这个request有可能因对NSURLProtocol 的 canonicalization 或 redirects 而发生改变; NSURLConnection
通过+connectionWithRequest:delegate:
a或-initWithRequest:delegate:
创建后会在当前的runloop立即执行,没必要发送-start
消息;NSURLConnection
通过-initWithRequest:delegate:startImmediately:创建不会立马执,调用
-scheduleWithRunLoop:forMode:或-setDelegateQueue:
可指定delegate回调的执行上下文,然后调用-start
启动加载. 在-start
之前如果没有显式的指runloop,就在当前的runloop模式下默认执行;- NSURLConnectionSynchronousLoading 分类的同步方法
+sendSynchronousRequest:returningResponse:error
会阻塞当前主线程run loop;NSURLConnectionQueuedLoading 分类的异步方法+sendAsynchronousRequest:queue:completionHandler
提供了异步机制,不会阻塞当前主线程的run loop。同时苹果不建意在加载自定资源时使用这两方法。
使用案例参考:iOS网络篇-NSURLConnection
- 同步请求:
//发送同步请求(sendSynchronousRequest) NSData *data = [NSURLConnection sendSynchronousRequest:requst returningResponse:&response error:&error];
- 异步请求:
//发送异步请求(sendAsynchronousRequest) [NSURLConnection sendAsynchronousRequest:requst queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { NSLog(@"----%@",[NSThread currentThread]); //解析数据 NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]); }];
- 代理请求:
@interface ViewController ()<NSURLConnectionDataDelegate>
...
@end
@implementation
//实现代理中的四个方法
//1.当接受到服务器响应的时候会调用:response(响应头)
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {...}
//2.当接受到服务器返回数据的时候调用(会调用多次)
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {...}
//3.当请求失败的时候调用
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{...}
//4.当请求结束(成功|失败)的时候调用
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {...}
//最后编写点击时调用的方法
-(void)sendRequestWithDelegate{
...
NSURLConnection *connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
//[connect cancel]; 取消
[connect start];
}
@end