GCD:Grand Central Dispatch(牛逼的中樞調度器)
GCD兩個重要的概念:任務猩谊、隊列
創(chuàng)建CGD:
- 定制任務
- 將任務添加到隊列中
隊列:
- 并發(fā)(異步)隊列(Concurrent dispatch queue):可以讓多個任務并發(fā)(同時)執(zhí)行讹堤,自動開啟多個線程同時執(zhí)行任務。并發(fā)只在異步函數(shù)下有效
- 串行隊列(Serial dispatch queue):讓任務一個接著一個的執(zhí)行(一個任務執(zhí)行完才能執(zhí)行下個任務)
GCD執(zhí)行任務的常用函數(shù):
- 同步:只能在當前線程中執(zhí)行任務宝泵,不具備開啟線程的能力(同步函數(shù)會立馬執(zhí)行)
- 異步:可以在新的線程中執(zhí)行任務好啰,具備開啟新線程的能力
代碼中獲取并發(fā)隊列:
// 創(chuàng)建并發(fā)隊列
dispatch_queue_t queue = dispatch_queue_create("com.weizuche.queue", DISPATCH_QUEUE_CONCURRENT);
// 獲取全局的并發(fā)隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
代碼中獲取串行隊列:
// 創(chuàng)建串行隊列
dispatch_queue_t queue = dispatch_queue_create("com.weizuche.queue", DISPATCH_QUEUE_SERIAL);
// 獲取主隊列,主隊列是GCD自帶的一種特殊的串行隊列儿奶,主隊列中的任務都會放到主線程中運行
/**
* 異步函數(shù) + 并發(fā)隊列:可以同時開啟多條線程
*/
- (void)asyncConcurrent {
NSLog(@"asyncConcurrent--------start");
/* 1.創(chuàng)建一個并發(fā)隊列
* label : 相當于隊列的名字框往,唯一的標示
* DISPATCH_QUEUE_CONCURRENT 并發(fā)隊列;DISPATCH_QUEUE_SERIAL 串行隊列
*/
// dispatch_queue_t queue = dispatch_queue_create("com.weizuche.queue", DISPATCH_QUEUE_CONCURRENT);
/* 1.獲得全局的并發(fā)隊列(GCD默認提供了全局的并發(fā)隊列闯捎,供整個程序使用椰弊,不需創(chuàng)建)
* dispatch_get_global_queue(long identifier, unsigned long flags)
* long identifier:隊列優(yōu)先級,下面列出的優(yōu)先級從高到低
* DISPATCH_QUEUE_PRIORITY_HIGH
* DISPATCH_QUEUE_PRIORITY_DEFAULT (默認)
* DISPATCH_QUEUE_PRIORITY_LOW
* DISPATCH_QUEUE_PRIORITY_BACKGROUND
* flags默認傳0
*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2.將任務加入隊列
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"1-----%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"2-----%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"3-----%@", [NSThread currentThread]);
}
});
NSLog(@"asyncConcurrent--------end");
}
結果:
image
/**
* 同步函數(shù) + 并發(fā)隊列:不會開啟新的線程
*/
- (void)syncConcurrent {
NSLog(@"syncConcurrent--------start");
// 1.獲得全局的并發(fā)隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2.將任務加入隊列
dispatch_sync(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"1-----%@", [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"2-----%@", [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"3-----%@", [NSThread currentThread]);
}
});
NSLog(@"syncConcurrent--------end");
}
結果:
image
/**
* 異步函數(shù) + 串行隊列:會開啟新的線程瓤鼻,但是任務是串行的秉版,執(zhí)行完一個任務,再執(zhí)行下一個任務
*/
- (void)asyncSerial {
NSLog(@"asyncSerial--------start");
// 1.創(chuàng)建串行隊列
dispatch_queue_t queue = dispatch_queue_create("com.weizuche.queue", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", NULL);
// 2.將任務加入隊列
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"1-----%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"2-----%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"3-----%@", [NSThread currentThread]);
}
});
NSLog(@"asyncSerial--------end");
}
結果:
image
/**
* 同步函數(shù) + 串行隊列:不會開啟新的線程娱仔,在當前線程執(zhí)行任務沐飘。任務是串行的,執(zhí)行完一個任務牲迫,再執(zhí)行下一個任務
*/
- (void)syncSerial {
NSLog(@"syncSerial--------start");
// 1.創(chuàng)建串行隊列
dispatch_queue_t queue = dispatch_queue_create("com.weizuche.queue", DISPATCH_QUEUE_SERIAL);
// 2.將任務加入隊列
dispatch_sync(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"1-----%@", [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"2-----%@", [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"3-----%@", [NSThread currentThread]);
}
});
NSLog(@"syncSerial--------end");
}
結果:
image
/**
* 異步函數(shù) + 主隊列:只在主線程中執(zhí)行任務耐朴,異步函數(shù)在主隊列上不會開啟線程
*/
- (void)asyncMain
{
NSLog(@"asyncMain ----- start");
// 1.獲得主隊列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.將任務加入隊列
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"1-----%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"2-----%@", [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (NSInteger i = 0; i<5; i++) {
NSLog(@"3-----%@", [NSThread currentThread]);
}
});
NSLog(@"asyncMain ----- end");
}
結果:
image
/**
* 同步函數(shù) + 主隊列:
*/
- (void)syncMain
{
NSLog(@"syncMain ----- begin");
// 1.獲得主隊列
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.將任務加入隊列
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
NSLog(@"syncMain ----- end");
}
結果:
image
出現(xiàn)這種情況的原因:主線程先執(zhí)行syncMain函數(shù),但是在syncMain函數(shù)中走到dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});的時候盹憎,因為這句話是同步主隊列中執(zhí)行筛峭,需要優(yōu)先執(zhí)行這句話,但是syncMain還沒執(zhí)行完陪每,同樣需要先執(zhí)行完syncMain函數(shù)影晓,造成沖突镰吵,所以就出現(xiàn)了上圖的情況。
線程之間的通信
dispatch_queue_t queue = dispatch_queue_create("11111", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 進行耗時的操作呢
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程進行UI刷新
});
});