讀AFNetworking源碼第五次的收穫與思考

咱們先從 NSURLConnection 作一個get請求:php

- (void)reqConnection {
    NSLog(@"異步請求測試開始...");
       NSURL *url = [NSURL URLWithString:@"http://ip.taobao.com/service/getIpInfo.php?ip=myip"];
       NSURLRequest *request = [NSURLRequest requestWithURL:url];
       
       NSLog(@"立刻進行異步鏈接請求url的數據");
       [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {//[NSOperationQueue currentQueue]決定block在哪一個隊列執行
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

           NSLog(@"data:%@",dict);
           if (data.length > 0 && connectionError == nil) {
               NSLog(@"%lu字節的數據被返回",(unsigned long)data.length);
           }else if (connectionError == nil && data.length == 0)
           {
               NSLog(@"沒有數據返回。。");
           }else if (connectionError != nil)
           {
               NSLog(@"返回錯誤");
           }
       }];
       NSLog(@"異步請求測試完成。。");
       
}

拋開原理不說,單從請求方式來講和 AF裏的 :html

//startImmediately 是否當即開始
 self.connection = [[[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO] autorelease];
    assert(self.connection != nil);
    
    for (NSString * mode in self.actualRunLoopModes) {
        [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode];
    }
    
    [self.connection start];

來分析思考下 有什麼區別:最上面的用的是block,下面這個用的是代理:網絡

@implementation ViewController

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    NSLog(@"接收到請求:%@",response);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    NSLog(@"didReceiveData dict:%@",dict);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://ip.taobao.com/service/getIpInfo.php?ip=myip"]];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
    [connection start];

接下來看看 這裏所謂的 runloop都在幹嗎?多線程

for (NSString * mode in self.actualRunLoopModes) {
        [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode];
    }

**能夠將NSTimer手動加入NSRunLoop,Cocoa庫也爲其它一些類提供了能夠手動加入NSRunLoop的方法,這些類有NSPort、NSStream、NSURLConnection、NSNetServices,方法都是[scheduleInRunLoop:forMode:]形式。我暫時只介紹下最經常使用的NSURLConnection類,看看如何把NSURLConnection的網絡下載加入到其它線程的run loop去運行。異步

若是NSURLConnection是在主線程中啓動的,實際上它就在主線程中運行 -- 並不是啓動的另外的線程,但又具有異步運行的特性,這個確實是run loop的巧妙所在。若是對run loop有了初步的瞭解和概念後,實際上就能明白NSURLConnection的運行,實際也是須要當前線程具有run loop。oop

  • (void)scheduleInRunLoop:(NSRunLoop )aRunLoop forMode:(NSString )mode; //將加入指定的run loop中運行,必須保證這時NSURLConnection不能啓動,不然不起做用了

如何讓NSURLConnection在子線程中運行,參考資料:https://blog.csdn.net/lengshengren/article/details/12905697測試

多線程:http://www.javashuo.com/article/p-xtgdggjj-hw.htmlurl

爲何別人都這麼經常使用多線程,而本身用的卻不多,因此好好留心 ,多思考 多用。.net

相關文章
相關標籤/搜索