了解完多線基礎概念和NSTread的基本使用后,本文介紹GCD的主要用方法
GCD全稱 : Grand Central Dispatch --偉大的中樞調(diào)度器
CGD的優(yōu)勢: 多核并行運算提出解決方案,自動管理線程生命周期,自動利用更多的CPU內(nèi)核
1 兩大核心概念
任務 : 執(zhí)行什么操作
隊列 : 用來存放任務
一般使用步驟: 定制任務,將任務添加到隊列甫题,GCD會自動將隊列中得任務取出巧鸭,放到對應的線程中執(zhí)行;任務取出順序晴叨,遵循FIFO凿宾,先進先出,后進后出兼蕊,
2 用來執(zhí)行任務的兩個函數(shù)
//同步執(zhí)行
dispatch_sync(dispatch_queue_t queue, ^(void)block)
//異步執(zhí)行
dispatch_async(dispatch_queue_t queue, ^(void)block)
* 參數(shù) queue 隊列
* 參數(shù) block 任務的代碼塊
- 兩者的區(qū)別
- 同步 : 不開啟新線程
- 異步 : 會開啟新線程
3 隊列的類型
GCD的隊列分為兩大類型
并發(fā)隊列 (Concurrent Dispatch Queue) : 多個任務并發(fā)(同時)執(zhí)行(自動開啟多個線程同時執(zhí)行),只有在異步函數(shù)下有效
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
參數(shù)1 : 隊列優(yōu)先級
參數(shù)2 : 默認 0
串行隊列 (Serial Dispatch Queue) : 一個任務執(zhí)行完成再接著執(zhí)行下一個
dispatch_queue_t queue = dispatch_queue_create("C語言的字符串-隊列標識", NULL);
4 四種情況分析
1. 異步執(zhí)行 全局并發(fā)隊列 添加5個任務
- 分析 "常用這種方式"
- 會不會創(chuàng)建線程 : 會創(chuàng)建5條子線程
- 任務的執(zhí)行方式 : 并發(fā)執(zhí)行
2. 異步執(zhí)行 串行隊列 添加5個任務
- 分析 "偶爾常用這種方式"
- 會不會創(chuàng)建線程 : 會創(chuàng)建1條子線程(不論添加多少個任務都只開啟一條)
- 任務的執(zhí)行方式 : 順序執(zhí)行
3. 同步執(zhí)行 全局并發(fā)隊列 添加5個任務
- 分析 "不常用"
- 會不會創(chuàng)建線程 : 不會開啟新的子線程
- 任務的執(zhí)行方式 : 順序執(zhí)行初厚,(因為只有一條線程所以只能順序執(zhí)行)
4. 同步執(zhí)行 串行隊列 添加5個任務
- 分析 "不常用"
- 會不會創(chuàng)建線程 : 不會開啟新的子線程
- 任務的執(zhí)行方式 : 順序執(zhí)行
5. 特殊情況 -- 異步執(zhí)行 串行主隊列 添加5個任務
// 獲取主隊列 這個也是一個串行隊列
dispatch_queue_t queue = dispatch_get_main_queue();
- 分析
- 會不會創(chuàng)建線程 : 不會開啟新的線程 因為主隊列對應的線程就是主線程,主線程只能有一個
- 任務的執(zhí)行方式 : 順序執(zhí)行
5 GCD線程之間的通信
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 耗時操作
dispatch_async(dispatch_get_main_queue(), ^{
// 主線程刷新UI
});
});
6 延遲執(zhí)行
1 下面這種方式會卡住主線程
[NSThread sleepForTimeInterval:2];
2 下面這種方式不會卡住主線程,但是不能改變延遲后代碼執(zhí)行的線程
[self performSelector:@selector(download:) withObject:@"下載中" afterDelay:2];
3 這種GCD的方式,比較好孙技,不卡住主線程产禾,也能隨意定制延遲后代碼執(zhí)行的線程
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)("時間"* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 延遲后要執(zhí)行的代碼
});
7 一次執(zhí)行
一次性執(zhí)行的代碼主要用來創(chuàng)建單例模式
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只執(zhí)行一次的代碼
});
8 隊列組
隊列組的功能主要是,當多個任務需要同時執(zhí)行牵啦,且所有任務都執(zhí)行完畢后亚情,還要觸發(fā)執(zhí)行別的任務的時候用到。
//獲取隊列組
dispatch_group_t group = dispatch_group_create();
//隊列組添加異步執(zhí)行任務
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
// 任務1代碼
});
.
添加多個任務
.
dispatch_group_async(group, queue, ^{
// 任務n代碼
});
.
dispatch_group_notify(group, queue, ^{
// 所有任務執(zhí)行完后喚醒需要執(zhí)行的代碼
});