多線程和AFN網(wǎng)絡(luò)框架配合使用

ios的多線程一般有NSOperation和GCD.
NSOperation基本使用:


    NSBlockOperation * operation1 = [NSBlockOperation blockOperationWithBlock:^{
   //任務(wù)A     
    }];
    NSBlockOperation * operation2 = [NSBlockOperation blockOperationWithBlock:^{
      //任務(wù)B   
    }];
    NSBlockOperation * operation3 = [NSBlockOperation blockOperationWithBlock:^{
     //任務(wù)C    
    }];
[operation2 addDependency:operation1];//添加依賴
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
    [queue addOperations:@[operation1,operation2,operation3] waitUntilFinished:NO];

GCD基本使用:

dispatch_queue_t queue = dispatch_queue_create("gcd_queue", DISPATCH_QUEUE_CONCURRENT);    
    dispatch_async(queue, ^{
        // 任務(wù)D
       
        }
    });
barrier:
dispatch_barrier_async(queue, ^{
        // 任務(wù)E
       //E會等待D完成后執(zhí)行,且E完成后才會執(zhí)行F哑蔫。其中barrier的queue是create才有這個作用,如果是全局隊列作用與dispatch_async一樣撩笆。
        }
    });
    dispatch_async(queue, ^{
        // 任務(wù)F
       
        }
    });
信號量
 //創(chuàng)建信號量并設(shè)置計數(shù)默認為0
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
//若計數(shù)為0則一直等待烫饼,當前線程阻塞起趾,信號量減一
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
//與wait配對使用唉锌,阻塞的線程會繼續(xù)執(zhí)行隅肥,信號量加一
dispatch_semaphore_signal(sema);

調(diào)度組
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
//任務(wù)1
    });
 dispatch_group_enter(_group);
dispatch_group_leave(_group);//成對出現(xiàn)添加、移除標記

 dispatch_group_notify(group, queue, ^{
//等待任務(wù)都執(zhí)行完后的監(jiān)聽袄简。
});

簡單的多線程都很好理解腥放。當實際開發(fā)中使用AFN框架時候,因為框架內(nèi)部網(wǎng)絡(luò)請求會自動實現(xiàn)多線程绿语,所以在使用時候難免會產(chǎn)生麻煩捉片。有時候會出現(xiàn)一個頁面多個網(wǎng)絡(luò)請求,有依賴關(guān)系或無依賴關(guān)系汞舱。下載功能的app,有可能遇到先并發(fā)執(zhí)行幾個任務(wù)宗雇,再執(zhí)行一個任務(wù)昂芜,之后再并發(fā)執(zhí)行幾個任務(wù)。下面就個人理解寫出解決方案赔蒲,當然不唯一泌神,但可以實現(xiàn)。
一舞虱、異步執(zhí)行A任務(wù)欢际,執(zhí)行后異步執(zhí)行B任務(wù),然后執(zhí)行C任務(wù)刷新UI矾兜。
解決:先利用NSOperation設(shè)置依賴關(guān)系损趋。保證執(zhí)行順序,因為NSOperation默認并發(fā)開辟了線程椅寺,AFN又開辟線程浑槽,所以可以利用信號量阻塞線程達到效果。

__weak typeof (self)weakSelf =self;
    
    NSBlockOperation * operation1 = [NSBlockOperation blockOperationWithBlock:^{
        [weakSelf requestA];
        
    }];
    NSBlockOperation * operation2 = [NSBlockOperation blockOperationWithBlock:^{
        [weakSelf requestB];
        
    }];
    NSBlockOperation * operation3 = [NSBlockOperation blockOperationWithBlock:^{
        [weakSelf requestC];
        
    }];
    [operation2 addDependency:operation1];
    [operation3 addDependency:operation2];
//保證執(zhí)行順序返帕。
    NSOperationQueue * queue = [[NSOperationQueue alloc]init];
    [queue addOperations:@[operation1,operation2,operation3] waitUntilFinished:NO];
-(void)requestA{
    
    //創(chuàng)建信號量并設(shè)置計數(shù)默認為0
    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    
    [AFNmanager GET:@"" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {        
        dispatch_semaphore_signal(sema);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //計數(shù)+1操作        
        dispatch_semaphore_signal(sema);
        
    }];

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

}

requestB與requestA類似桐玻。因為依賴關(guān)系保證了執(zhí)行順序,AFN開辟新線程后荆萤,調(diào)用了wait函數(shù)镊靴,阻塞了requestA的線程,導(dǎo)致B任務(wù)無法開啟,然而AFN開辟的線程還可以繼續(xù)執(zhí)行偏竟。請求結(jié)束后回調(diào)煮落,signal函數(shù)使requestA所在線程不再阻塞。轉(zhuǎn)向B任務(wù)線程苫耸。以此類推州邢,執(zhí)行到C,C直接主線程刷新UI褪子。

-(void)requestC{
      dispatch_async(dispatch_get_main_queue(), ^{

            //更新UI操作

        });
}

二量淌、異步無序執(zhí)行A、B任務(wù)后執(zhí)行C任務(wù)刷新UI嫌褪。(兩種思路呀枢,還有更多不再列舉)
1.調(diào)度組實現(xiàn)

 _group = dispatch_group_create();
        [self loadA];
        [self loadB];
      dispatch_group_notify(_group, dispatch_get_main_queue(), ^{
            [self reloadUI];
        });

- (void) loadA {//loadB與loadA相似
        dispatch_group_enter(_group);
 [AFNmanager GET:@"" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {        
          dispatch_group_leave(_group);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
             dispatch_group_leave(_group);
        
    }];      
    }

2.調(diào)度組異步+信號量實現(xiàn)

- (void) loadData {
  // 創(chuàng)建信號量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    // 創(chuàng)建全局并行
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
//任務(wù)A
[AFNmanager GET:@"" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {        
       dispatch_semaphore_signal(semaphore);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         dispatch_semaphore_signal(semaphore);
        
    }];      
       
    });
    dispatch_group_async(group, queue, ^{
//任務(wù)B
[AFNmanager GET:@"" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {        
       dispatch_semaphore_signal(semaphore);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         dispatch_semaphore_signal(semaphore);
        
    }];      
       
    });
}

[self loadData];
 dispatch_group_notify(group, queue, ^{

        // 2個請求對應(yīng)2次信號等待
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
//在這里減2,AB任務(wù)完后信號量加了2笼痛,才可以繼續(xù)執(zhí)行裙秋,只要AB中任何一個沒有執(zhí)行完,就會阻塞在wait這缨伊。
        //在這里 進行請求后的方法摘刑,回到主線程
        dispatch_async(dispatch_get_main_queue(), ^{
            //更新UI操作
        });

    });   

三、多任務(wù)并發(fā)后執(zhí)行一個任務(wù)后繼續(xù)多任務(wù)并發(fā)執(zhí)行刻坊。

dispatch_queue_t queue = dispatch_queue_create("gcd_queue", DISPATCH_QUEUE_CONCURRENT); 

    dispatch_async(queue, ^{  //任務(wù)1     任務(wù)2枷恕、3等類似于1。  
      dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
         [AFNmanager GET:@"" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {        
        dispatch_semaphore_signal(semaphore);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //計數(shù)+1操作        
        dispatch_semaphore_signal(semaphore);
        
    }];
//阻塞任務(wù)1所在線程谭胚,等待執(zhí)行結(jié)束后不再阻塞
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        }
    });
dispatch_barrier_async(queue, ^{
  //前面的并發(fā)任務(wù)執(zhí)行完后執(zhí)行   內(nèi)部類似于任務(wù)1.

        }
    });
    dispatch_async(queue, ^{
        // 后面的并發(fā)任務(wù)加不加信號量控制都可以徐块。
       
        }
    });
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市灾而,隨后出現(xiàn)的幾起案子胡控,更是在濱河造成了極大的恐慌,老刑警劉巖旁趟,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昼激,死亡現(xiàn)場離奇詭異,居然都是意外死亡轻庆,警方通過查閱死者的電腦和手機癣猾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余爆,“玉大人纷宇,你說我怎么就攤上這事《攴剑” “怎么了像捶?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵上陕,是天一觀的道長。 經(jīng)常有香客問我拓春,道長释簿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任硼莽,我火速辦了婚禮庶溶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘懂鸵。我一直安慰自己偏螺,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布匆光。 她就那樣靜靜地躺著套像,像睡著了一般。 火紅的嫁衣襯著肌膚如雪终息。 梳的紋絲不亂的頭發(fā)上夺巩,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音周崭,去河邊找鬼柳譬。 笑死,一個胖子當著我的面吹牛续镇,可吹牛的內(nèi)容都是我干的征绎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼磨取,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柴墩?” 一聲冷哼從身側(cè)響起忙厌,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎江咳,沒想到半個月后逢净,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡歼指,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年爹土,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片踩身。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡胀茵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挟阻,到底是詐尸還是另有隱情琼娘,我是刑警寧澤峭弟,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站脱拼,受9級特大地震影響瞒瘸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜熄浓,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一情臭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赌蔑,春花似錦俯在、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至石景,卻和暖如春劈猿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背潮孽。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工揪荣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人往史。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓仗颈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親椎例。 傳聞我的和親對象是個殘疾皇子挨决,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時...
    歐辰_OSR閱讀 29,405評論 8 265
  • iOS多線程編程 基本知識 1. 進程(process) 進程是指在系統(tǒng)中正在運行的一個應(yīng)用程序,就是一段程序的執(zhí)...
    陵無山閱讀 6,064評論 1 14
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,109評論 1 32
  • Object C中創(chuàng)建線程的方法是什么订歪?如果在主線程中執(zhí)行代碼脖祈,方法是什么?如果想延時執(zhí)行代碼刷晋、方法又是什么盖高? 1...
    AlanGe閱讀 1,746評論 0 17
  • 睜開最純凈的雙眸,朦朦朧朧眼虱,映入眼簾的是一個身著白衣的喻奥,臉上漾著笑意的阿姨,她的名字叫“白衣天使“捏悬。就是這樣一個天...
    慧子沒有故事閱讀 212評論 0 0