iOS-Network学习笔记(二)——NSURLConnection
2016-06-01 21:43
525 查看
1. NSURLConnection简介
(1)构造函数和调度函数
- (nullable
instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable
id)delegate startImmediately:(BOOL)startImmediately
该方法是NSURLConnection的默认构造函数,startImmediately参数,如果为YES,代表会将当前的connection实例加入到当前的runloop中,该connection的delegate的回调方法都会在当前线程执行,自动实现调度,所以这种情况下甚至是不需要调用 -start方法来开始请求;如果为NO,则需要手动调度,将当前的connection加入到一个线程的runloop中(如果不添加,默认会添加到当前线程的runloop中)。
- (nullable
instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable
id)delegate
+ (nullable
NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(nullable
id)delegate
上述的实例构造函数和类构造的本质是一样的,最终会调用到默认构造函数,startImmediately参数为YES。
NSURLConnection的执行必须是在一个开启runloop的线程中的,如果执行线程没有开启runloop,connection在start之后,可能会收不到回调方法。PS:主线程的runloop默认是开启的。
在某些开源的网络框架中,开始一个connection的时候,都会开启当前线程的runloop,比如AFNetworking中,所有的网络请求都是在一个特定的线程中执行,这个线程在初始化的时候就开启一个runloop。
+ (void)networkRequestThreadEntryPoint:(id)__unused
object {
@autoreleasepool
{
[[NSThread
currentThread]
setName:@"AFNetworking"];
NSRunLoop
*runLoop = [NSRunLoop
currentRunLoop];
[runLoop
addPort:[NSMachPort
port]
forMode:NSDefaultRunLoopMode];
[runLoop
run];
}
}
+ (NSThread
*)networkRequestThread {
static
NSThread
*_networkRequestThread =
nil;
static
dispatch_once_t
oncePredicate;
dispatch_once(&oncePredicate, ^{
_networkRequestThread = [[NSThread
alloc]
initWithTarget:self
selector:@selector(networkRequestThreadEntryPoint:)
object:nil];
[_networkRequestThread
start];
});
return
_networkRequestThread;
}
SDWebImage框架中,没有特定某个线程来执行connection,而是让operat
da34
ionqueue来分配线程执行,所以在connection start的时候,会开启当前线程的runloop
if
(floor(NSFoundationVersionNumber)
<=
NSFoundationVersionNumber_iOS_5_1) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode,
10,
false);
}
else {
CFRunLoopRun();
}
手动调度函数有下面三个,前两个是设置/取消connection 回调方法所在的runloop中,第三个直接设置一个operationQueue,将connection的delegate的回调方法交给 queue来调度
- (void)scheduleInRunLoop:(NSRunLoop
*)aRunLoop forMode:(NSRunLoopMode)mode NS_AVAILABLE(10_5,
2_0);
- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSRunLoopMode)mode NS_AVAILABLE(10_5,
2_0);
- (void)setDelegateQueue:(nullable
NSOperationQueue*) queue NS_AVAILABLE(10_7,
5_0);
(2)start和cancel
start的方法调用时机,是NSURLConnection创建时startImmediately为NO的时候,要手动调用;cancel方法,提供给我们一个手动结束这个网络连接。-cancel方法,是理论上终止这个网络连接,但是也有可能不起任何作用,deleagte回调方法还会继续;但是如果确定被cancel,delegate就会被释放。
(3)canHandleRequest方法
这个方法,是判断能否通过一个request实例化一个connection。处理方式,是判断这个request能否被请求,正式发送之前的例行检查。
(4)两个category
两个category提供了两个类方法,同步加载以及异步加载,简单处理结果(block回调的形式)。代码如下,第一个是同步加载,会阻塞当前线程;第二个是异步加载,同时会有一个回调block,处理成功的data或者是失败的error
+ (nullable
NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *
__nullable
*
__nullable)response error:(NSError **)error
+ (void)sendAsynchronousRequest:(NSURLRequest*)
request
queue:(NSOperationQueue*) queue
completionHandler:(void
(^)(NSURLResponse*
__nullable response, NSData*
__nullable
data, NSError*
__nullable connectionError)) handler
2. NSURLConnection Delegate
(1)NSURLConnectionDelegate
- (void)connection:(NSURLConnection
*)connection didFailWithError:(NSError *)error;
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge
*)challenge;
如上代码:第一个方法是在connection发生error后进行的回调,(最多回调一次),只要进行回调之后,delegate之后就不会再有回调的方法;第二个是询问connection实例要不要CredentialStorage,不管返回是Y/N,都三个回调都会进行调用的;都三个是connection连接需要进行认证相关的操作回调
(2)NSURLConnectionDataDelegate
- (nullable
NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(nullable
NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse
*)response;
- (void)connection:(NSURLConnection
*)connection didReceiveData:(NSData *)data;
- (nullable
NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request;
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
- (nullable
NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
如上代码:该delegate是将网络数据存储在内存中的回调。第一个方法,是在需要改变request(重定向)的时候,返回一个request来进行继续加载,当然也可以返回nil(connection就会被终止,delegate回调会继续直到finish/error,一般情况下是error);第二个方法,是在收到服务器的响应时进行调用的;第三个方法,是获得网络数据的回调(可能多次调用);第四个方法,是在需要给request增加一些请求body的情况下进行调用的(连接错误或者认证错误),返回nil将会cancel这个connection;第五个方法,是在上传过程中,提供的process回调,(可以计算百分比);第六个方法,是要不要将这个connection的response缓存起来,下次调用可以直接从缓存拿(返回nil,就不能拿;如果进行缓存了,request的参数设置成可以从缓存拿,才会拿着个缓存);最后一个方法,是connection完成的回调。
(3)NSURLConnectionDownloadDelegate
- (void)connection:(NSURLConnection
*)connection didWriteData:(long
long)bytesWritten totalBytesWritten:(long
long)totalBytesWritten expectedTotalBytes:(long
long) expectedTotalBytes;
- (void)connectionDidResumeDownloading:(NSURLConnection *)connection
totalBytesWritten:(long
long)totalBytesWritten expectedTotalBytes:(long
long) expectedTotalBytes;
- (void)connectionDidFinishDownloading:(NSURLConnection
*)connection destinationURL:(NSURL *) destinationURL;
如上代码:该delegate是将网络数据存储在文件中的回调。第一个方法,是获取当前写到文件中的进度;第二个方法是获取断点续传的进度;最后一个方法是必须要实现的,连接结束,提供了暂时存储文件的临时URL,我们需要的是将这个文件的数据转移(如果需要),之后这个临时文件就会被释放。
(1)构造函数和调度函数
- (nullable
instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable
id)delegate startImmediately:(BOOL)startImmediately
该方法是NSURLConnection的默认构造函数,startImmediately参数,如果为YES,代表会将当前的connection实例加入到当前的runloop中,该connection的delegate的回调方法都会在当前线程执行,自动实现调度,所以这种情况下甚至是不需要调用 -start方法来开始请求;如果为NO,则需要手动调度,将当前的connection加入到一个线程的runloop中(如果不添加,默认会添加到当前线程的runloop中)。
- (nullable
instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable
id)delegate
+ (nullable
NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(nullable
id)delegate
上述的实例构造函数和类构造的本质是一样的,最终会调用到默认构造函数,startImmediately参数为YES。
NSURLConnection的执行必须是在一个开启runloop的线程中的,如果执行线程没有开启runloop,connection在start之后,可能会收不到回调方法。PS:主线程的runloop默认是开启的。
在某些开源的网络框架中,开始一个connection的时候,都会开启当前线程的runloop,比如AFNetworking中,所有的网络请求都是在一个特定的线程中执行,这个线程在初始化的时候就开启一个runloop。
+ (void)networkRequestThreadEntryPoint:(id)__unused
object {
@autoreleasepool
{
[[NSThread
currentThread]
setName:@"AFNetworking"];
NSRunLoop
*runLoop = [NSRunLoop
currentRunLoop];
[runLoop
addPort:[NSMachPort
port]
forMode:NSDefaultRunLoopMode];
[runLoop
run];
}
}
+ (NSThread
*)networkRequestThread {
static
NSThread
*_networkRequestThread =
nil;
static
dispatch_once_t
oncePredicate;
dispatch_once(&oncePredicate, ^{
_networkRequestThread = [[NSThread
alloc]
initWithTarget:self
selector:@selector(networkRequestThreadEntryPoint:)
object:nil];
[_networkRequestThread
start];
});
return
_networkRequestThread;
}
SDWebImage框架中,没有特定某个线程来执行connection,而是让operat
da34
ionqueue来分配线程执行,所以在connection start的时候,会开启当前线程的runloop
if
(floor(NSFoundationVersionNumber)
<=
NSFoundationVersionNumber_iOS_5_1) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode,
10,
false);
}
else {
CFRunLoopRun();
}
手动调度函数有下面三个,前两个是设置/取消connection 回调方法所在的runloop中,第三个直接设置一个operationQueue,将connection的delegate的回调方法交给 queue来调度
- (void)scheduleInRunLoop:(NSRunLoop
*)aRunLoop forMode:(NSRunLoopMode)mode NS_AVAILABLE(10_5,
2_0);
- (void)unscheduleFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSRunLoopMode)mode NS_AVAILABLE(10_5,
2_0);
- (void)setDelegateQueue:(nullable
NSOperationQueue*) queue NS_AVAILABLE(10_7,
5_0);
(2)start和cancel
start的方法调用时机,是NSURLConnection创建时startImmediately为NO的时候,要手动调用;cancel方法,提供给我们一个手动结束这个网络连接。-cancel方法,是理论上终止这个网络连接,但是也有可能不起任何作用,deleagte回调方法还会继续;但是如果确定被cancel,delegate就会被释放。
(3)canHandleRequest方法
这个方法,是判断能否通过一个request实例化一个connection。处理方式,是判断这个request能否被请求,正式发送之前的例行检查。
(4)两个category
两个category提供了两个类方法,同步加载以及异步加载,简单处理结果(block回调的形式)。代码如下,第一个是同步加载,会阻塞当前线程;第二个是异步加载,同时会有一个回调block,处理成功的data或者是失败的error
+ (nullable
NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *
__nullable
*
__nullable)response error:(NSError **)error
+ (void)sendAsynchronousRequest:(NSURLRequest*)
request
queue:(NSOperationQueue*) queue
completionHandler:(void
(^)(NSURLResponse*
__nullable response, NSData*
__nullable
data, NSError*
__nullable connectionError)) handler
2. NSURLConnection Delegate
(1)NSURLConnectionDelegate
- (void)connection:(NSURLConnection
*)connection didFailWithError:(NSError *)error;
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge
*)challenge;
如上代码:第一个方法是在connection发生error后进行的回调,(最多回调一次),只要进行回调之后,delegate之后就不会再有回调的方法;第二个是询问connection实例要不要CredentialStorage,不管返回是Y/N,都三个回调都会进行调用的;都三个是connection连接需要进行认证相关的操作回调
(2)NSURLConnectionDataDelegate
- (nullable
NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(nullable
NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse
*)response;
- (void)connection:(NSURLConnection
*)connection didReceiveData:(NSData *)data;
- (nullable
NSInputStream *)connection:(NSURLConnection *)connection needNewBodyStream:(NSURLRequest *)request;
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
- (nullable
NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
如上代码:该delegate是将网络数据存储在内存中的回调。第一个方法,是在需要改变request(重定向)的时候,返回一个request来进行继续加载,当然也可以返回nil(connection就会被终止,delegate回调会继续直到finish/error,一般情况下是error);第二个方法,是在收到服务器的响应时进行调用的;第三个方法,是获得网络数据的回调(可能多次调用);第四个方法,是在需要给request增加一些请求body的情况下进行调用的(连接错误或者认证错误),返回nil将会cancel这个connection;第五个方法,是在上传过程中,提供的process回调,(可以计算百分比);第六个方法,是要不要将这个connection的response缓存起来,下次调用可以直接从缓存拿(返回nil,就不能拿;如果进行缓存了,request的参数设置成可以从缓存拿,才会拿着个缓存);最后一个方法,是connection完成的回调。
(3)NSURLConnectionDownloadDelegate
- (void)connection:(NSURLConnection
*)connection didWriteData:(long
long)bytesWritten totalBytesWritten:(long
long)totalBytesWritten expectedTotalBytes:(long
long) expectedTotalBytes;
- (void)connectionDidResumeDownloading:(NSURLConnection *)connection
totalBytesWritten:(long
long)totalBytesWritten expectedTotalBytes:(long
long) expectedTotalBytes;
- (void)connectionDidFinishDownloading:(NSURLConnection
*)connection destinationURL:(NSURL *) destinationURL;
如上代码:该delegate是将网络数据存储在文件中的回调。第一个方法,是获取当前写到文件中的进度;第二个方法是获取断点续传的进度;最后一个方法是必须要实现的,连接结束,提供了暂时存储文件的临时URL,我们需要的是将这个文件的数据转移(如果需要),之后这个临时文件就会被释放。
相关文章推荐
- Android Manifest 用法
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 什么是 GraphQL?
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- Spark RDD API详解(一) Map和Reduce
- Spring Boot 开发微服务
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- lwn拾遗:[sn3218 led drivers]-api解释-1
- 页面元素查找之Selectors API
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 一个小型js框架myJSFrame附API使用帮助
- 详细分析交换机、路由器、集线器的区别和联系
- PowerShell打开或关闭光驱
- 批处理的api WMIC学习体会有感第1/2页
- 批处理 API实现文件下载的代码第1/2页
- Lua教程(十七):C API简介
- 强制删除工具 xdelbox xdelbox1.5正式版下载