- 蘋果公司為多核的并行運(yùn)算提供的解決方案
- 會(huì)自動(dòng)利用更多的CPU內(nèi)核
- 會(huì)自動(dòng)管理線程的生命周期
幾個(gè)概念(同步 異步 串行 并行)
同步/異步關(guān)系到能否開啟新線程
- 同步: 只是在當(dāng)前線程中執(zhí)行, 不具備開線程的能力
- 異步: 可以在新的線程中執(zhí)行, 具備開線程的能力
串行/并行主要影響 任務(wù)的執(zhí)行方式
- 并發(fā): 允許多個(gè)任務(wù)(并發(fā))同步執(zhí)行
- 串行: 一個(gè)任務(wù)執(zhí)行完畢后, 再執(zhí)行另一個(gè)任務(wù)
基本使用
- 異步函數(shù)+并發(fā)隊(duì)列 (會(huì)開啟多條線程, 隊(duì)列中任務(wù)并發(fā)執(zhí)行)
// 1.創(chuàng)建隊(duì)列
/*
第一個(gè)參數(shù): C語言字符串 隊(duì)列標(biāo)簽區(qū)分不同隊(duì)列
第二個(gè)參數(shù): 隊(duì)列類型
DISPATCH_QUEUE_CONCURRENT: 并行隊(duì)列
DISPATCH_QUEUE_SERIAL: 串行隊(duì)列
*/
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);
// 2.封裝任務(wù)
/*
第一個(gè)參數(shù): 隊(duì)列
第二個(gè)參數(shù): 代碼塊
*/
// 異步
dispatch_async(q, ^{
// 執(zhí)行代碼
});
- 異步函數(shù)+串行隊(duì)列 (會(huì)開啟線程, 隊(duì)列中任務(wù)前進(jìn)先出)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL);
// 2.封裝任務(wù)
dispatch_async(q, ^{
// 執(zhí)行代碼
});
- 同步函數(shù)+并發(fā)隊(duì)列 (不會(huì)開啟線程, 任務(wù)串行執(zhí)行)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);
// 2.封裝任務(wù)
dispatch_sync(q, ^{
// 執(zhí)行代碼
});
- 同步函數(shù)+串行隊(duì)列 (不會(huì)開啟線程, 任務(wù)串行執(zhí)行)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_SERIAL);
// 2.封裝任務(wù)
dispatch_sync(q, ^{
// 執(zhí)行代碼
});
- 異步函數(shù)+主隊(duì)列
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_get_main_queue();
// 2.封裝任務(wù)
dispatch_async(q, ^{
// 執(zhí)行代碼
});
- 同步函數(shù)+主隊(duì)列 (死鎖)
// 1.創(chuàng)建隊(duì)列
dispatch_queue_t q = dispatch_get_main_queue();
// 2.封裝任務(wù)
// 同步函數(shù): 如果我沒有執(zhí)行完, 后面不能執(zhí)行
dispatch_sync(q, ^{
// 執(zhí)行代碼
NSLog(@"download1------%@",[NSThread currentThread]);
});
dispatch_sync(q, ^{
// 執(zhí)行代碼
NSLog(@"download2------%@",[NSThread currentThread]);
});
dispatch_sync(q, ^{
// 執(zhí)行代碼
NSLog(@"download3------%@",[NSThread currentThread]);
});
線程間通訊
// 創(chuàng)建子線程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 執(zhí)行任務(wù)
/*
......
*/
// 回主線程更新
dispatch_async(dispatch_get_main_queue(), ^{
// 更新UI
});
});
GCD常用函數(shù)
// 延時(shí)
-(void)delay{
// 常規(guī)方法一
[self performSelector:@selector(task) withObject:nil afterDelay:2.0];
// 常規(guī)方法二
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
// GCD方法 (可以控制執(zhí)行的線程)
/*
第一個(gè)參數(shù): DISPATCH_TIME_NOW 從現(xiàn)在開始計(jì)算時(shí)間
第二個(gè)參數(shù): 延遲時(shí)間 GCD時(shí)間單位是納秒
第三個(gè)參數(shù): 隊(duì)列
*/
// dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
});
}
// 一次性代碼
-(void)once{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
});
}
// 柵欄函數(shù)
-(void)zhalan
{
// 1.創(chuàng)建隊(duì)列
// dispatch_queue_t q = dispatch_get_global_queue(0, 0);
dispatch_queue_t q = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);
// 2.封裝任務(wù)
dispatch_async(q, ^{
// 執(zhí)行代碼
NSLog(@"download1------%@",[NSThread currentThread]);
});
// 柵欄函數(shù)不能使用全局并發(fā)隊(duì)列
dispatch_barrier_async(q, ^{
// 柵欄函數(shù)上面的任務(wù)先執(zhí)行, 下面的函數(shù)后執(zhí)行
});
dispatch_async(q, ^{
// 執(zhí)行代碼
NSLog(@"download2------%@",[NSThread currentThread]);
});
dispatch_async(q, ^{
// 執(zhí)行代碼
NSLog(@"download3------%@",[NSThread currentThread]);
});
}
// 快速遍歷
-(void)apply
{
/*
第一個(gè)參數(shù): 遍歷次數(shù)
第二個(gè)參數(shù): 隊(duì)列(必須是并發(fā)隊(duì)列)
第三個(gè)參數(shù): 索引
*/
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t idx) {
// 內(nèi)部開多個(gè)子線程和主線程一起完成任務(wù) 任務(wù)的執(zhí)行是并發(fā)的
});
}
// 隊(duì)列組
-(void)queueGroup1
{
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_async(queue, ^{
NSLog(@"1---------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2---------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3---------%@",[NSThread currentThread]);
});
// 需求: 三個(gè)任務(wù)都完成后執(zhí)行其他操作
dispatch_group_async(group, queue, ^{
NSLog(@"1---------%@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"2---------%@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"3---------%@",[NSThread currentThread]);
});
dispatch_group_notify(group, queue, ^{
// 隊(duì)列組任務(wù)執(zhí)行完后 執(zhí)行此方法
});
// 死等 必須任務(wù)組中任務(wù)都執(zhí)行完畢才能執(zhí)行 阻塞的 (與dispatch_group_notify作用相同)
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}
GCD補(bǔ)充知識(shí)點(diǎn)
-(void)supplement
{
// block封裝
dispatch_async(dispatch_get_global_queue(0, 0), ^{
});
// 函數(shù)式封裝
/*
第一個(gè)參數(shù): 隊(duì)列
第二個(gè)參數(shù): 參數(shù)
第三個(gè)參數(shù): 要調(diào)用的函數(shù)名稱
*/
dispatch_async_f(dispatch_get_global_queue(0, 0), NULL, task);
}
void task(void *param)
{
}