iOS 異步請(qǐng)求等待傳值方法小結(jié)

前言

  • 總感覺這個(gè)標(biāo)題怪怪的,但是我自身詞匯有限,也不知道怎么描述好了.用一個(gè)簡(jiǎn)單的需求來解釋一下吧.我之前開發(fā)的一個(gè)項(xiàng)目,需要向服務(wù)器上傳圖片,多圖片上傳,然后每次上傳之后會(huì)返回一個(gè)圖片的AID, 然后需要所有圖片上傳完成之后, 拿著一個(gè)全是AID的數(shù)組作為參數(shù)進(jìn)行另一個(gè)異步請(qǐng)求...好吧,我感覺又繞了...

  • 前幾天,我在一個(gè)技術(shù)交流圈,看到一個(gè)朋友去JINGDONG的面試題, 其中一個(gè)題目的描述是:有a、b、c、d 4個(gè)異步請(qǐng)求,如何判斷a、b、c、d都完成執(zhí)行?, 跟我上面的需求大同小異.

  • 所以在這兒,我把我工作中曾經(jīng)用到過的一些方法做一個(gè)小的總結(jié),有遺漏的或者錯(cuò)誤的地方,請(qǐng)大家留意指正,非常感謝哈!!!

  • 特別注意:所有的代碼都基于JINGDONG這道面試題, 不過我只打印了A和B而已..

小結(jié)

1. RunLoop

  • 需要注意一點(diǎn): 這兒用的是NSURLSession, 不是AFN, 所以block里面的線程是子線程,不是主線程, 不能直接使用CFRunLoopGetCurrent
  • CFRunLoopGetCurrent : Returns the CFRunLoop object for the current thread.
  • CFRunLoopGetMain: Returns the main CFRunLoop object.
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"A");
        CFRunLoopStop(CFRunLoopGetMain());
    }] ;
    [task resume];
 CFRunLoopRun();
 NSLog(@"B");

2. GCD的group

  • dispatch_group_notify就是需要等queue里面的子線程都執(zhí)行完畢之后才會(huì)執(zhí)行
  • 這種方法比較常見, 不多說
dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_async(group, queue, ^{
        NSLog(@"A");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"B");
    });

3. dispatch_barrier_async

  • barrier的中文意思就是障礙, 屏障
  • 一般使用dispatch_barrier_async, 會(huì)讓barrier之前的線程執(zhí)行完成之后才會(huì)執(zhí)行barrier后面的操作
 dispatch_queue_t queue =  dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"A");
    });
    dispatch_async(queue, ^{
        NSLog(@"C");
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"拿到了A的值");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"D");
    });
    dispatch_async(queue, ^{
        NSLog(@"E");
    });dispatch_async(queue, ^{
        NSLog(@"F");
    });

4.NSOperationQueue

  • 主要就是用到NSOperationQueue的一個(gè)對(duì)象方法-addDependency
  • 需要注意一點(diǎn): waitUntilFinished如果是YES,必須等到queue中所有Operation執(zhí)行完畢之后, 才會(huì)打印HAHA, 反之的話, HAHA的打印順序是隨機(jī)的了,就看哪個(gè)線程跑得快了...
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSBlockOperation *p1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A");
    }];
    NSBlockOperation *p2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B");
    }];
    NSBlockOperation *p3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C");
    }];
    [p3 addDependency:p1];
    [p3 addDependency:p2];
    // waitUntilFinished是否阻塞當(dāng)前線程
    [queue addOperations:@[p1,p2,p3] waitUntilFinished:NO];
    
    // 如果是NO,那么這行打印就是隨機(jī)的, 反之就是等A,B,C都打印完之后才執(zhí)行
    NSLog(@"HAHA");

5. 使用AFN中的batchOfRequestOperations

  • 這個(gè)和GCD一樣, 我工作中比較常用的一種方法
  • batchOfRequestOperations方法其實(shí)是AFHTTPRequestOperation的父類AFURLConnectionOperation的一個(gè)方法.
  • 這兒的waitUntilFinished4. NSOperationQueue
  • progressBlock一般用在進(jìn)度計(jì)算中, 比如執(zhí)行了多少百分比, 可以自定義一些炫酷動(dòng)畫
AFHTTPRequestOperation *queue = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
    [queue setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"A");
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"A");
    }];
    [queue resume];
    
    AFHTTPRequestOperation *queue2 = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
    [queue2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"B");
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"B");
    }];
    [queue2 resume];
    
    NSArray *operations = [AFHTTPRequestOperation batchOfRequestOperations:@[queue, queue2] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
        NSLog(@"%ld/%ld", numberOfFinishedOperations, totalNumberOfOperations);
    } completionBlock:^(NSArray *operations) {
        NSLog(@"C");
    }];
    
    [[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];

6.其他

  • 老早以前, 我一般是在一個(gè)異步請(qǐng)求中的completionBlock或者successBlock中拿到需要的值, 為空判斷后,直接在block里面再寫一個(gè)異步線程...其實(shí)這樣的寫法可能很多人都用過,但是代碼的閱讀性太弱了,花括號(hào)太多,看的眼花繚亂的...
  • 其實(shí)還可以設(shè)置flag進(jìn)行判斷等等方法...
  • 暫時(shí)就想到這么多, 還有別的方案的話, 歡迎留言哈,大家共同學(xué)習(xí)!!!

聯(lián)系我

<a >github</a>

<a >微博</a>

<a href="http://www.itdecent.cn/users/9723687edfb5/latest_articles">簡(jiǎn)書</a>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 總感覺這個(gè)標(biāo)題怪怪的,但是我自身詞匯有限,也不知道怎么描述好了.用一個(gè)簡(jiǎn)單的需求來解釋一下吧.我之前開發(fā)的一個(gè)項(xiàng)目...
    90后的思維閱讀 369評(píng)論 0 1
  • 在這篇文章中,我將為你整理一下 iOS 開發(fā)中幾種多線程方案,以及其使用方法和注意事項(xiàng)。當(dāng)然也會(huì)給出幾種多線程的案...
    張戰(zhàn)威ican閱讀 692評(píng)論 0 0
  • NSThread 第一種:通過NSThread的對(duì)象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 952評(píng)論 0 3
  • 概述 這篇文章中,我不會(huì)說多線程是什么、線程和進(jìn)程的區(qū)別、多線程有什么用,當(dāng)然我也不會(huì)說什么是串行、什么是并行等問...
    hashakey閱讀 366評(píng)論 0 0
  • 學(xué)習(xí)多線程,轉(zhuǎn)載兩篇大神的帖子,留著以后回顧!第一篇:關(guān)于iOS多線程,你看我就夠了 第二篇:GCD使用經(jīng)驗(yàn)與技巧...
    John_LS閱讀 734評(píng)論 0 3

友情鏈接更多精彩內(nèi)容