- Grand Central Dispatch:純C語言
- GCD為多核的并行而生
- GCD自動管理線程生命周期(創建,調度,銷毀)
1.GCD的線程分配規則
2.四個重要概念
- 同步異步說的是函數的開啟新線程的能力
- 同步:不具備開啟新線程能力,只在當前線程中執行任務
- 異步:具備開啟新線程的能力,可在多條線程中執行任務
- 并發串行說的是任務的執行順序
- 串行:任務一個接一個的執行
- 并發:任務一起執行
3.使用語法:
- 并發隊列
dispatch_queue_t queue = dispatch_queue_create("downloadA", DISPATCH_QUEUE_CONCURRENT);
- 串行隊列
dispatch_queue_t queueA = dispatch_queue_create("downloadB", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queueB = dispatch_queue_create("downloadB", NULL);
- 全局并發隊列
// 獲取全局并發隊列
dispatch_queue_t queueA = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queueB = dispatch_get_global_queue(0, 0);
- 主隊列
//1.獲得主隊列
dispatch_queue_t queue = dispatch_get_main_queue();
- 異步函數
dispatch_async(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
- 同步函數
dispatch_sync(queue, ^{
NSLog(@"download1----%@",[NSThread currentThread]);
});
4.線程間通信
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 執行耗時的異步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主線程,執行UI刷新操作
});
});
5.GCD常用函數
5.1.延遲執行
- 延遲執行的第一種方法:performSelector
[self performSelector:@selector(task) withObject:nil afterDelay:2.0];
- 2.延遲執行的第二種方法:NSTimer
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
- 3.延遲執行的第三種方法:GCD
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
/*
第一個參數:DISPATCH_TIME_NOW 從現在開始計算時間
第二個參數:延遲的時間 2.0 GCD時間單位:納秒
第三個參數:隊列
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
NSLog(@"GCD----%@",[NSThread currentThread]);
});
5.2.一次性代碼
//不能放在懶加載中的,應用場景:單例模式
-(void)once
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"---once----");
});
}
5.3.柵欄函數:
- 柵欄函數不能使用全局并發隊列,否則 dispatch_barrier_async 的作用會和 dispatch_async 的作用一樣
// 創建并發隊列
dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);
// 并發隊列 + 異步函數任務1
dispatch_async(queue, ^{
for (NSInteger i = 0; i<100; i++) {
NSLog(@"download1-%zd-%@",i,[NSThread currentThread]);
}
});
// 并發隊列 + 異步函數任務2
dispatch_async(queue, ^{
for (NSInteger i = 0; i<100; i++) {
NSLog(@"download2-%zd-%@",i,[NSThread currentThread]);
}
});
//并發隊列 + 柵欄函數
dispatch_barrier_async(queue, ^{
NSLog(@"+++++++++++++++++++++++++++++");
});
// 并發隊列 + 異步函數任務3
dispatch_async(queue, ^{
for (NSInteger i = 0; i<100; i++) {
NSLog(@"download3-%zd-%@",i,[NSThread currentThread]);
}
});
5.4.快速迭代
/*
迭代函數
第一個參數:遍歷的次數
第二個參數:隊列(并發隊列)
第三個參數:index 索引
*/
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){
// 執行10次代碼,index順序不確定
});
6.隊列組
-(void)group1
{
//1.創建隊列
dispatch_queue_t queue =dispatch_get_global_queue(0, 0);
//2.創建隊列組
dispatch_group_t group = dispatch_group_create();
//3.異步函數
/*
1)把任務添加到隊列中
2)隊列添加到隊列組
3)監聽任務的執行情況, 通知group
*/
dispatch_group_async(group, queue, ^{
NSLog(@"1----%@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"2----%@",[NSThread currentThread]);
});
// 當隊列組中所有的任務都執行完畢, 進入到下面的方法
dispatch_group_notify(group, queue, ^{
NSLog(@"-------dispatch_group_notify-------");
});
}
- 使用異步函數,在并發隊列中可開啟多條線程;在串行隊列中只開啟一條線程;在主隊列中不能開啟新線程。
- 注意:同步函數 + 主隊列 = 死鎖