iOS多線程:GCD Group、Barrier和NSOperationQueue

GCD系列文章

GCD任務(wù)和隊(duì)列使用詳解


本文主要總結(jié)GCD Group、Barrier和NSOperationQueue相關(guān)方法使用邏輯。

某些情況下會(huì)遇到多個(gè)任務(wù)并行處理、或任務(wù)間有依賴關(guān)系的操作。如果自己創(chuàng)建線程并管理線程之間資源競(jìng)爭(zhēng)關(guān)系,比較復(fù)雜,而使用GCD或NSOperationQueue會(huì)方便快捷很多。

  1. GCD Group
    GCD Group主要使用場(chǎng)景為多個(gè)任務(wù)并發(fā)執(zhí)行,在所有任務(wù)執(zhí)行完成后通知。注意點(diǎn)是
    dispatch_group_enter(group)、dispatch_group_leave(group)成對(duì)使用,表示將任務(wù)加入
    隊(duì)列和任務(wù)離開(kāi)隊(duì)列,dispatch_group_leave(group)要在當(dāng)前任務(wù)完成后調(diào)用,
    dispatch_group_notify中的block會(huì)在加入組隊(duì)列的所有任務(wù)結(jié)束后調(diào)用。
//創(chuàng)建group
dispatch_group_t group = dispatch_group_create();

場(chǎng)景:從多個(gè)服務(wù)端接口獲取數(shù)據(jù),所有數(shù)據(jù)獲取成功后,刷新UI

使用GCD Group實(shí)現(xiàn)代碼如下:

- (void)testGCD_GROUP
{
    NSLog(@"%@",NSStringFromSelector(_cmd));
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(arc4random()%5+1);
        NSLog(@"異步從獲取網(wǎng)絡(luò)數(shù)據(jù)1");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(arc4random()%5+1);
        NSLog(@"異步從獲取網(wǎng)絡(luò)數(shù)據(jù)2");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"刷新UI");
    });
}

使用GCD_Barrier代碼如下:

/*
barrier主要適用于分離多個(gè)并發(fā)任務(wù),如并發(fā)任務(wù)(1,2,3)執(zhí)行完成后執(zhí)行任務(wù)4,
任務(wù)4執(zhí)行完成后執(zhí)行其他任務(wù),就可以使用dispatch_barrier將任務(wù)4加入隊(duì)列,
任務(wù)4就像柵欄一樣把任務(wù)(1,2,3)和任務(wù)4之后的任務(wù)分離開(kāi)。
*/
- (void)testGCD_Barrier
{
    NSLog(@"%@",NSStringFromSelector(_cmd));
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        sleep(arc4random()%5+1);
        NSLog(@"異步從獲取網(wǎng)絡(luò)數(shù)據(jù)1");
    });
    dispatch_async(queue, ^{
        sleep(arc4random()%5+1);
        NSLog(@"異步從獲取網(wǎng)絡(luò)數(shù)據(jù)2");
    });
    
    dispatch_barrier_async(queue, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"UI");
        });
    });
}

使用NSOperationQueue實(shí)現(xiàn)如下:

/*
操作隊(duì)列基于GCD封裝,可以替代GCD使用。
*/
- (void)testOperation
{
    NSLog(@"%@",NSStringFromSelector(_cmd));
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        sleep(arc4random()%5+1);
        NSLog(@"任務(wù)1");
    }];
    
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        sleep(arc4random()%5+1);
        NSLog(@"任務(wù)2");
    }];
    
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        sleep(arc4random()%5+1);
        NSLog(@"UI");
    }];
    operation.qualityOfService = NSQualityOfServiceUserInteractive;
    //添加依賴關(guān)系:operation依賴operation1、operation2
   //添加依賴的效果就是operation會(huì)在operation1、operation2都執(zhí)行完成后執(zhí)行
    [operation addDependency:operation1];
    [operation addDependency:operation2];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperations:@[operation,operation1,operation2] waitUntilFinished:NO];
}

三種方式都能實(shí)現(xiàn)有順序的多任務(wù)管理

  1. GCD Group最適合多任務(wù)并發(fā),等待所有任務(wù)完成后,再執(zhí)行其他任務(wù)。
  2. GCD Barrier適合多個(gè)任務(wù)分批執(zhí)行的場(chǎng)景,可以方便的把每一批任務(wù)隔離開(kāi),如其名柵欄。
  3. NSOperationQueue實(shí)現(xiàn)具有更高的可讀性,提供取消任務(wù)、管理并發(fā)數(shù)量、線程優(yōu)先級(jí)等接口。
最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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