GCD系列文章
本文主要總結(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ì)方便快捷很多。
- 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ù)管理
- GCD Group最適合多任務(wù)并發(fā),等待所有任務(wù)完成后,再執(zhí)行其他任務(wù)。
- GCD Barrier適合多個(gè)任務(wù)分批執(zhí)行的場(chǎng)景,可以方便的把每一批任務(wù)隔離開(kāi),如其名柵欄。
- NSOperationQueue實(shí)現(xiàn)具有更高的可讀性,提供取消任務(wù)、管理并發(fā)數(shù)量、線程優(yōu)先級(jí)等接口。