GCD是最常用的管理并行代碼和執(zhí)行異步操作的Unix系統(tǒng)層的API。GCD構(gòu)造和管理隊(duì)列中的任務(wù)酌儒。
隊(duì)列是什么?
隊(duì)列是按先進(jìn)先出(FIFO)管理對(duì)象的數(shù)據(jù)結(jié)構(gòu)断盛。
調(diào)度隊(duì)列!
調(diào)度隊(duì)列是一種簡(jiǎn)單的異步和同步任務(wù)的方法戚宦。
串行隊(duì)列!
當(dāng)你選擇創(chuàng)建一個(gè)串行隊(duì)列锈嫩,隊(duì)列一次只能執(zhí)行一個(gè)任務(wù)受楼。
使用串行隊(duì)列的優(yōu)點(diǎn)是:
1.保證序列化訪問(wèn)共享資源,避免競(jìng)態(tài)條件呼寸。
2.任務(wù)的執(zhí)行順序是可預(yù)測(cè)的艳汽。當(dāng)你提交任務(wù)到一個(gè)串行調(diào)度隊(duì)列,它們將按插入的順序執(zhí)行对雪。
3.你可以創(chuàng)建任意數(shù)量的串行隊(duì)列河狐。
并行隊(duì)列!
顧名思義,并行隊(duì)列可以并行執(zhí)行多個(gè)任務(wù)瑟捣。
使用隊(duì)列
1馋艺、并行隊(duì)列
默認(rèn)情況下,系統(tǒng)為每個(gè)應(yīng)用提供了一個(gè)串行隊(duì)列和四個(gè)并行隊(duì)列迈套。
使用一個(gè)全局并行隊(duì)列捐祠,你必須得到隊(duì)列的引用,使用函數(shù)dispatch_get_global_queue桑李,它的第一個(gè)參數(shù)是:
DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_BACKGROUND
2踱蛀、串行隊(duì)列
解決滯后問(wèn)題的備用方法是使用串行隊(duì)列。每個(gè)應(yīng)用都有一個(gè)默認(rèn)的串行隊(duì)列贵白,這實(shí)際上是用于UI的主隊(duì)列率拒。所以記住當(dāng)使用串行隊(duì)列時(shí),你必須創(chuàng)建一個(gè)新隊(duì)列禁荒,否則會(huì)在應(yīng)用試圖執(zhí)行更新UI的任務(wù)的時(shí)候執(zhí)行你的任務(wù)俏橘。這將導(dǎo)致錯(cuò)誤和延遲,破壞用戶體驗(yàn)圈浇。你可以使用函數(shù)dispatch_queue_create來(lái)創(chuàng)建一個(gè)新隊(duì)列寥掐,
dispatch_queue_create("com.app.www", DISPATCH_QUEUE_SERIAL);
操作隊(duì)列
不同于GCD靴寂,它們不按先進(jìn)先出的順序。下面是操作隊(duì)列和調(diào)度隊(duì)列的不同點(diǎn):
1.不遵循先進(jìn)先出:在操作隊(duì)列中召耘,你可以設(shè)置一個(gè)操作的執(zhí)行優(yōu)先級(jí)百炬,你可以添加操作之間的依賴關(guān)系,這意味著你可以定義一些操作完成后才會(huì)執(zhí)行其他操作污它。這就是為什么它們不遵循先進(jìn)先出剖踊。
2.默認(rèn)情況下,它們同時(shí)操作:然而你不能把它的類型改變成串行隊(duì)列衫贬。通過(guò)使用操作之間的依賴關(guān)系德澈,在操作隊(duì)列還存在一個(gè)工作區(qū)來(lái)依次執(zhí)行任務(wù)。
3.操作隊(duì)列是類NSOperationQueue的實(shí)例固惯,其任務(wù)封裝在NSOperation的實(shí)例里梆造。
NSOperation
任務(wù)以NSOperation實(shí)例的形式提交到操作隊(duì)列。
1.NSBlockOperation——使用這個(gè)類來(lái)用一個(gè)或多個(gè)block初始化操作葬毫。操作本身可以包含多個(gè)塊镇辉。當(dāng)所有block被執(zhí)行操作將被視為完成。
2.NSInvocationOperation——使用這個(gè)類來(lái)初始化一個(gè)操作贴捡,它包括指定對(duì)象的調(diào)用selector忽肛。
下面貼上我簡(jiǎn)單的示例代碼
// NSBlockOperation直接操作隊(duì)列執(zhí)行任務(wù)
// 通過(guò)它最關(guān)鍵的是設(shè)置任務(wù)被執(zhí)行完后還能執(zhí)行block
// 可以取消任務(wù),關(guān)聯(lián)任務(wù)(依賴)
- (void)blockOperation
{
// 創(chuàng)建隊(duì)列
NSOperationQueue *queue = [NSOperationQueue currentQueue];
// 創(chuàng)建任務(wù)
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我創(chuàng)建了第一個(gè)任務(wù)");
}];
// 任務(wù)執(zhí)行完畢后的回調(diào)方法
blockOperation.completionBlock = ^(){
NSLog(@"任務(wù)執(zhí)行完畢");
};
// 往隊(duì)列中添加任務(wù)
[queue addOperation:blockOperation];
// 取消任務(wù)
[queue cancelAllOperations];
NSBlockOperation *dependencyBlock = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我先執(zhí)行");
}];
// 創(chuàng)建依賴
[blockOperation addDependency:dependencyBlock];
}
// 操作隊(duì)列(NSOpreationQueue)
- (void)opreationQueue
{
// 創(chuàng)建一個(gè)單元隊(duì)列(NSOperationQueue是OC對(duì)象,
// 是蘋果封裝了GCD而設(shè)計(jì)的一套框架)
NSOperationQueue *queue = [NSOperationQueue currentQueue];
// 向隊(duì)列中提交任務(wù)烂斋,可以提交多個(gè)屹逛,當(dāng)所有的任務(wù)被執(zhí)行完
// 才算是這一次操作被執(zhí)行完畢
[queue addOperationWithBlock:^{
NSLog(@"我是第一個(gè)操作");
// 在更新UI時(shí),我們可以使用它提交到系統(tǒng)的主隊(duì)列
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"更新UI界面");
}];
}];
}
// GCD的應(yīng)用
- (void)dispatch_async
{
// 并行隊(duì)列(系統(tǒng)有4種不同類型的并行隊(duì)列)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 串行隊(duì)列(系統(tǒng)默認(rèn)的串行隊(duì)列)
// dispatch_queue_t DefaultQueue = dispatch_get_main_queue();
// 提交并發(fā)任務(wù)到queue中(我們可以創(chuàng)建多個(gè)并發(fā)任務(wù)以及串行任務(wù)汛骂,
// 任務(wù)之間是相互不影響的罕模,只有在開始順序以及執(zhí)行順序上
// 會(huì)有些許不同)
dispatch_async(queue, ^{
NSLog(@"我是并發(fā)任務(wù)");
});
// 提交串行任務(wù)到defaultQueue中
// 這樣在其實(shí)應(yīng)該是更新UI時(shí),而執(zhí)行了下列方法香缺,因而
// 我們可以創(chuàng)建一個(gè)隊(duì)列,然后將其提交至串行隊(duì)列中
// DISPATCH_QUEUE_SERIAL表明是串行隊(duì)列(一連串的)
// dispatch_queue_t newQueue = dispatch_queue_create(@"com.app.www", DISPATCH_QUEUE_SERIAL);
// 因?yàn)檫@是C語(yǔ)言代碼歇僧,所以應(yīng)該是“”
dispatch_queue_t newQueue = dispatch_queue_create("com.app.www", DISPATCH_QUEUE_SERIAL);
dispatch_sync(newQueue, ^{
NSLog(@"我是串行任務(wù)");
});
// dispatch_async與dispatch_sync是指添加任務(wù)到隊(duì)列中的方式图张,有同步跟異步,同步是指等添加進(jìn)隊(duì)列中的任務(wù)執(zhí)行完再添加下一個(gè)任務(wù)诈悍,異步是無(wú)需等待祸轮,直接添加
}