iOS-Network学习笔记(二)——NSURLConnection

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,而是让operationqueue来分配线程执行,所以在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,我们需要的是将这个文件的数据转移(如果需要),之后这个临时文件就会被释放。

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值