GCD: GCD的核心概念就是把任務(wù)添加到隊列中,指定任務(wù)執(zhí)行的方法.
1 :任務(wù),使用Block封裝好的代碼段就是一個任務(wù).
2 :隊列,分串行隊列,并發(fā)隊列2種:
串行: 1個一個的調(diào)任務(wù),主線程也是串行隊列
并發(fā): 可以同時調(diào)度多個任務(wù),
3 :執(zhí)行: 執(zhí)行又分同步執(zhí)行和異步執(zhí)行:
同步: 同步執(zhí)行每個任務(wù)不完成的時候不會執(zhí)行下一個命令
異步: 當(dāng)前任務(wù)不完成一樣可以執(zhí)行下一個命令.
隊列類型:
// 隊列類型
dispatch_queue_t
創(chuàng)建一個隊列:
// dispatch_queue_t 返回值隊列
// const char *label 隊列名字
// dispatch_queue_attr_t attr 隊列類型
dispatch_queue_t
dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
dispatch_queue_attr_t 隊列類型:
DISPATCH_QUEUE_SERIAL : 串行隊列 ,等待執(zhí)行中的處理結(jié)果.
DISPATCH_QUEUE_CONCURRENT : 并發(fā)隊列,不等待執(zhí)行中的處理結(jié)果.
實(shí)例:創(chuàng)造一個隊列
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL);
獲得一個全局的并發(fā)隊列:
// dispatch_queue_t 返回值一個隊列
// long identifier 隊列的優(yōu)先級
// unsigned long flags 傳 0
dispatch_queue_t
dispatch_get_global_queue(long identifier, unsigned long flags);
隊列的優(yōu)先級:
ios7
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 高級
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默認(rèn)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) 低級
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后臺
ios8
QOS_CLASS_USER_INTERACTIVE 用戶希望線程快點(diǎn)執(zhí)行完畢,不要使用耗時操作
QOS_CLASS_USER_INITIATED 用戶需要的,不要使用耗時操作QOS_CLASS_DEFAULT 默認(rèn)
QOS_CLASS_UTILITY 耗時操作
QOS_CLASS_BACKGROUND 后臺
QOS_CLASS_UNSPECIFIED 0 未指定優(yōu)先級
實(shí)例:
dispatch_queue_t queget = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
獲取一個當(dāng)前的主隊列:
// dispatch_queue_t 隊列 這里返回的是主隊列
dispatch_queue_t
dispatch_get_main_queue(void)
實(shí)例:
dispatch_queue_t mainque = dispatch_get_main_queue();
線程之間的執(zhí)行順序:
同步執(zhí)行:
void
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
同步串行實(shí)例: 這里的代碼將 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因?yàn)槭谴械乃詴粋€一個執(zhí)行,因?yàn)槭峭綀?zhí)行,所以在一個執(zhí)行完以前不會執(zhí)行下一個.并且不會開新線程.
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL);
for (int i = 0 ; i<10; i++) {
dispatch_sync(que, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
同步并發(fā)實(shí)例:這里的代碼將 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,雖然是并發(fā)隊列了,但是因?yàn)槭峭綀?zhí)行的原因,在一個代碼執(zhí)行完成之前,不能執(zhí)行另外一個任務(wù),所以仍然一個一個執(zhí)行,并且不會開啟新的線程.
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0 ; i<10; i++) {
dispatch_sync(que, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
異步執(zhí)行:
// dispatch_queue_t queue 隊列
// dispatch_block_t block 封裝的代碼段
void
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
異步執(zhí)行串行隊列實(shí)例: 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因?yàn)槭钱惒綀?zhí)行所以會再另開一條線程去執(zhí)行,而又因?yàn)槭谴嘘犃?在一個任務(wù)執(zhí)行完成前不會執(zhí)行下一個所以只開1條線程,并且主線程繼續(xù)執(zhí)行.
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_SERIAL);
for (int i = 0 ; i<10; i++) {
dispatch_async(que, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
異步執(zhí)行并發(fā)隊列實(shí)例: 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因?yàn)槭钱惒綀?zhí)行所以會再另開一條線程去執(zhí)行,而又因?yàn)槭遣l(fā)隊列,在一個任務(wù)執(zhí)行完成前就會開一條新線程繼續(xù)執(zhí)行直到一個執(zhí)行完,會開幾條 新線程.
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0 ; i<10; i++) {
dispatch_async(que, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
主線程的同步死鎖實(shí)例: 程序會卡主.主隊列在等待 dispatch_sync
調(diào)度完任務(wù)才會向下執(zhí)行,而dispatch_sync
也在等待主隊列執(zhí)行完才會執(zhí)行
dispatch_queue_t mainque = dispatch_get_main_queue();
for (int i = 0 ; i<10; i++) {
dispatch_sync(mainque, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
NSLog(@"結(jié)束");
主線程的異步實(shí)例:先執(zhí)行完主線程,在執(zhí)行dispatch_async
dispatch_queue_t mainque = dispatch_get_main_queue();
for (int i = 0 ; i<10; i++) {
dispatch_async(mainque, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
解決同步死鎖的方法:用異步的方式先開啟子線程,在回到主線程同步執(zhí)行
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t mainque = dispatch_get_main_queue();
dispatch_async(que, ^{
NSLog(@"%@",[NSThread currentThread]);
for (int i = 0 ; i<10; i++) {
dispatch_sync(mainque, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
});
延遲執(zhí)行:
將一段代碼延遲執(zhí)行:
// dispatch_time_t when 要延遲多少時間
// dispatch_queue_t queue 在哪個線程執(zhí)行
// dispatch_block_t block執(zhí)行的代碼段.
void
dispatch_after(dispatch_time_t when,
dispatch_queue_t queue,
dispatch_block_t block);
得出dispatch_time_t when
延遲時間
// 一個固定計算的公式 返回值是秒數(shù)
dispatch_time_t
dispatch_time(dispatch_time_t when, int64_t delta);
實(shí)例:
// <#delayInSeconds#> 這里寫秒數(shù) 如3.0.
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)
完整實(shí)例:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"3秒到了");
});
整個程序只執(zhí)行一次:
只調(diào)用一次:
// dispatch_once_t *predicate 一個標(biāo)記 是一個long類型傳入的是這個類型的地址&
// dispatch_block_t block 這個代碼段在程序中,只調(diào)用一次.
_dispatch_once(dispatch_once_t *predicate, dispatch_block_t block)
實(shí)例:
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"只調(diào)用1次");
});
組:
調(diào)度組:
// 調(diào)度組的類型
DISPATCH_DECL(dispatch_group);
dispatch_group_t group;
生成一個調(diào)度組
// dispatch_group_t 返回一個調(diào)度組.
dispatch_group_t
dispatch_group_create(void);
實(shí)例:
dispatch_group_t group = dispatch_group_create();
將一個任務(wù)異步的方式添加到調(diào)度組中
// dispatch_group_t group 哪個組
// dispatch_queue_t queue 哪個隊列
// dispatch_block_t block 任務(wù)執(zhí)行的代碼段
void
dispatch_group_async(dispatch_group_t group,
dispatch_queue_t queue,
dispatch_block_t block);
實(shí)例:
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, que, ^{
NSLog(@"%@ 隊列0",[NSThread currentThread]);
});
當(dāng)調(diào)度組線程與任務(wù)執(zhí)行完后:
當(dāng)一個調(diào)度組執(zhí)行完后執(zhí)行的代碼,這種等待是異步的,如果在這段代碼下寫了其他代碼會先執(zhí)行其他代碼 等調(diào)度組的所有任務(wù)線程都執(zhí)行完畢后才會執(zhí)行dispatch_group_notify
中的代碼.
// dispatch_group_t group 哪個調(diào)度組
// dispatch_queue_t queue 哪個隊列
// dispatch_block_t block 執(zhí)行的代碼段
void
dispatch_group_notify(dispatch_group_t group,
dispatch_queue_t queue,
dispatch_block_t block);
實(shí)例:
dispatch_group_notify(group, mainque, ^{
NSLog(@"執(zhí)行完了");
});
同步等待調(diào)度組回調(diào):
// dispatch_group_t group 哪個組
// dispatch_time_t timeout 等待時間
long
dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);
實(shí)例
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
標(biāo)記: 進(jìn)入組與離開組:
// 進(jìn)入組的標(biāo)志
void
dispatch_group_enter(dispatch_group_t group);
// 離開組的標(biāo)志
void
dispatch_group_leave(dispatch_group_t group);
一個小實(shí)例
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
void(^test)() = ^{
NSLog(@"測試");
dispatch_group_leave(group);
};
dispatch_async(dispatch_get_global_queue(0, 0), test);
dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"執(zhí)行完成");
});
NSLog(@"先執(zhí)行否");