GCD 是蘋果APP開發(fā)(Objective-c)中管理線程的一種方式!
涉及到線程 就有兩個很重要的概念 任務 和 隊列
任務: 任務就是需要執(zhí)行的一項操作 在執(zhí)行操作的時候又 可以分為 同步和異步執(zhí)行方式料扰!
--- 同步執(zhí)行: 不開辟新的線程旨巷,就占用當前的線程 來執(zhí)行這項任務 (不具備開辟新線程的能力)!
--- 異步執(zhí)行: 在和當前線程 不同的另一個線程中執(zhí)行任務 (具有開辟新線程的能力)!
隊列 : 這里的隊列是指任務隊列,遵守FIFO ( first in first out)特性放仗! 隊列有兩種類型 串行隊列 和 并行隊列
--- 串行隊列 : 單通道(好比只有一條水管流水)享言,一個接一個的執(zhí)行隊列中任務桑嘶!
執(zhí)行特點:在 全部并發(fā)隊列蒋搜、手工創(chuàng)建串行隊列、主隊列 中都沒有開啟新線程褐着,串行特性執(zhí)行任務!
--- 并行隊列 :多通道 (好比坷澡,有多個水管同時流水),多個任務可以同時執(zhí)行(多個水管中的水可以同時流出)含蓉!
執(zhí)行特點: 在全局并發(fā)隊列 中有開啟了新的線程并行執(zhí)行任務
在自己創(chuàng)建的隊列中 有開啟新線程 串行特性執(zhí)行任務
在主隊列中 沒有開啟新線程 串行特性執(zhí)行任務
GCD 使用步驟 :
1.明確定制任務频敛,根據(jù)任務的特點 (同步還是異步) 選擇 合適的隊列類型(串行還是并行)!
2. 將任務加入到多列之中馅扣!
3.系統(tǒng)根據(jù)任務類型 或者開新線程 或者不開新線程 斟赚、根據(jù) 隊列類型 來取出一個任務或者多個任務開始執(zhí)行!
同步函數(shù)和異步函數(shù)
dispatch_sync(queue, ^{
NSLog(@"同步函數(shù)");
});
dispatch_async(queue, ^{
NSLog(@"異步函數(shù)");
});
獲取幾種隊列 :
//主隊列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 串行隊列
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL);
// 并行隊列
dispatch_queue_t queue1 = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);
//全部并發(fā)隊列
dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
幾種任務和隊列的配合方式:
//1.同步函數(shù) + 串行隊列
// 串行隊列
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"同步函數(shù) + 串行隊列");
});
//2.異步函數(shù) + 串行隊列
// 串行隊列
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"異步函數(shù) + 串行隊列");
});
//3.同步函數(shù) + 并行隊列
// 串行隊列
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"同步函數(shù) + 并行隊列");
});
//4.異步函數(shù) + 并行隊列
// 串行隊列
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"異步函數(shù) + 并行隊列");
});
//主隊列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSLog(@"主隊列 + 異步函數(shù)");
});
dispatch_sync(mainQueue, ^{
NSLog(@"主隊列 + 同步函數(shù)");
});
//全局并發(fā)隊列 + 同步函數(shù) 實現(xiàn)線程依賴一次執(zhí)行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 5; i++) {
dispatch_sync(queue, ^{
NSLog(@"for -- 1 -- %d",i);
});
}
for (int i = 0; i < 5; i++) {
dispatch_sync(queue, ^{
NSLog(@"for -- 2 -- %d",i);
});
}
結(jié)果:
for -- 1 -- 0
for -- 1 -- 1
for -- 1 -- 2
for -- 1 -- 3
for -- 1 -- 4
for -- 2 -- 0
for -- 2 -- 1
for -- 2 -- 2
for -- 2 -- 3
for -- 2 -- 4
//全局并發(fā)隊列 + 異步函數(shù) 開啟新線程并發(fā)執(zhí)行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 5; i++) {
dispatch_async(queue, ^{
NSLog(@"for -- 1 -- %d",i);
});
}
for (int i = 0; i < 5; i++) {
dispatch_async(queue, ^{
NSLog(@"for -- 2 -- %d",i);
});
}
結(jié)果:
** for -- 1 -- 1**
** for -- 1 -- 0**
** for -- 1 -- 2**
** for -- 1 -- 3**
** for -- 1 -- 4**
** for -- 2 -- 0**
** for -- 2 -- 1**
** for -- 2 -- 2**
** for -- 2 -- 3**
回主線程 (用于更新UI)
dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"%@",[NSThread currentThread]); });
延時執(zhí)行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"1.5s后執(zhí)行內(nèi)容");
});
單利模式用到的一次性
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只執(zhí)行1次的代碼(這里面默認是線程安全的
)});