GCD(Grand Central Dispatch)中央調度器程序員
使用GCD只要理解兩個東西 (任務 、隊列);線程的建立和銷燬都不須要程序員管理,很是方便好用。併發
1、基本使用app
一、異步+並行隊列 : 開啓新的線程,多任務同時執行。異步
//建立隊列 /* 建立併發隊列 dispatch_queue_create(隊列標籤, 隊列類型); 隊列類型: DISPATCH_QUEUE_CONCURRENT 並行/併發 DISPATCH_QUEUE_SERIAL 串行 */ dispatch_queue_t queue1 = dispatch_queue_create("queue.label", DISPATCH_QUEUE_CONCURRENT); /* 獲取全局併發隊列 dispatch_get_global_queue(優先級:通常使用Defaul, 這個暫時沒用,填0就能夠了); 優先級:從上往下 DISPATCH_QUEUE_PRIORITY_HIGH 2 DISPATCH_QUEUE_PRIORITY_DEFAULT 0 DISPATCH_QUEUE_PRIORITY_LOW (-2) DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN */ dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//通常使用全局併發隊列 /* dispatch_async 異步 dispatch_sync 同步 */ dispatch_async(queue2, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---01----:%@",[NSThread currentThread]); } }); dispatch_async(queue2, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---02----:%@",[NSThread currentThread]); } }); dispatch_async(queue2, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---03----:%@",[NSThread currentThread]); } });
二、異步+串行隊列 : 開啓新的線程,單任務一個一個執行。async
//建立隊列 /* 建立併發隊列 dispatch_queue_create(隊列標籤, 隊列類型); 隊列類型: DISPATCH_QUEUE_CONCURRENT 並行/併發 DISPATCH_QUEUE_SERIAL 串行 */ // dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue = dispatch_queue_create("queue.label", NULL);//能夠填NULL,表明串行隊列 /* dispatch_async 異步 dispatch_sync 同步 */ dispatch_async(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---01----:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---02----:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---03----:%@",[NSThread currentThread]); } });
三、異步+主隊列 : 不啓新的線程,串行執行。spa
//獲取主隊列 dispatch_queue_t queue = dispatch_get_main_queue(); /* dispatch_async 異步 dispatch_sync 同步 */ dispatch_async(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---01----:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---02----:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---03----:%@",[NSThread currentThread]); } });
通常用於從子線程回到主線程線程
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//通常使用全局併發隊列 dispatch_async(queue, ^{ //任務 //這裏使用dispatch_async,異步回到主線程,而不會阻塞當前線程繼續往下執行,若是須要等待主線程執行完成再往下執行就使用同步dispatch_sync dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"回到主線程"); }); // NSLog(@"這裏還有執行內容。。"); });
四、同步+串行隊列 :不開啓新的線程,在主線程中執行。code
//同步只能夠用串行隊列,就算設置爲DISPATCH_QUEUE_CONCURRENT並行隊列也是無效的 //建立隊列 // dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue = dispatch_queue_create("queue.label", NULL);//能夠填NULL,表明串行隊列 /* dispatch_async 異步 dispatch_sync 同步 */ dispatch_sync(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---01----:%@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---02----:%@",[NSThread currentThread]); } }); dispatch_sync(queue, ^{ //任務 for (int i =0; i < 10; i++) { NSLog(@"---03----:%@",[NSThread currentThread]); } });
五、同步+主隊列 : 相互等待,形成線程堵塞,不執行,因此不能這麼使用。orm
NSLog(@"synMain -- start"); //獲取主隊列 dispatch_queue_t queue = dispatch_get_main_queue(); /* dispatch_async 異步 dispatch_sync 同步 */ dispatch_sync(queue, ^{ //任務 NSLog(@"---01----:%@",[NSThread currentThread]); }); NSLog(@"synMain -- end"); //打印結果 只會打印第一句 synMain -- start 而後就不執行了
六、barrier 特色:先執行barrier以前因此隊列中的任務,再執行barrier的任務,等barrier的任務執行完成,再執行在隊列中barrier以後的全部任務。blog
dispatch_queue_t queue = dispatch_queue_create("12312312", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"----1-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----2-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----3-----%@", [NSThread currentThread]); }); dispatch_barrier_async(queue, ^{ NSLog(@"----barrier-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----4-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----5-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----6-----%@", [NSThread currentThread]); }); //執行結果:如今併發執行 1 2 3任務,再執行barrier任務 ,再併發執行 4 5 6 任務。
七、延遲執行
//默認放在dispatch_get_main_queue主隊列中執行,能夠改 //延遲2秒 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //延遲執行的代碼 }); //其餘方式 // [self performSelector:@selector(run) withObject:nil afterDelay:2.0]; // [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:NO];
八、一次性代碼 : 用於單利比較多。
//一次性代碼 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //執行一次性代碼,在整個程序運行期間只會執行一次。 });
九、快速迭代/快速遍歷 :開啓多個線程同時執行任務。
//會快速開不一樣的線程去執行 //dispatch_apply(執行次數, 隊列, ^(size_t index); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_apply(10, queue, ^(size_t index) { //快速迭代的代碼,如:資料遷移。。等等。 });
十、隊列組
//建立一個隊列組 dispatch_group_t group = dispatch_group_create(); //建立一個隊列 // 0表明默認的優先級DISPATCH_QUEUE_PRIORITY_DEFAULT dispatch_queue_t queue = dispatch_get_global_queue(0, 0); // 建立組 dispatch_group_async(group, queue, ^{ //第一個組的操做 // 好比:請求1。。。 的代碼 }); // 建立組 dispatch_group_async(group, queue, ^{ //第二個組的操做 // 好比:請求2。。。 的代碼 }); // dispatch_group_notify(group, dispatch_get_main_queue(), ^{ //當隊列組都執行完成後就執行這裏 NSLog(@"兩個隊列中的任務都執行完成了"); });