1郎嫁、前言
GCD的學(xué)習(xí)中一定要理解任務(wù)秉继,同步、異步泽铛,串行尚辑、并發(fā)的概念,以及他們之間相互結(jié)合運(yùn)行的效果盔腔。
2杠茬、GCD的基本概念
- 任務(wù):任務(wù)就是將要在線程中執(zhí)行的代碼,用block快封裝好弛随,添加到指定的執(zhí)行方式瓢喉,等待CPU從隊(duì)列中取出任務(wù)放到對(duì)應(yīng)的線程中執(zhí)行。
- 同步:任務(wù)一個(gè)接著一個(gè)的執(zhí)行舀透,前一個(gè)執(zhí)行完栓票,后一個(gè)才開始執(zhí)行;不開啟新的線程盐杂。
- 異步:任務(wù)同一時(shí)間可以一起執(zhí)行逗载;開啟多個(gè)新的線程哆窿。
- 隊(duì)列:裝在線程任務(wù)的隊(duì)形結(jié)構(gòu),有串行隊(duì)列和并發(fā)隊(duì)列兩種隊(duì)列厉斟。
- 并發(fā)隊(duì)列:線程可以同一時(shí)間一起執(zhí)行挚躯。
- 串行隊(duì)列:線程只能依次有序的執(zhí)行。
3擦秽、隊(duì)列的創(chuàng)建方法
隊(duì)列的創(chuàng)建方法是使用:
dispatch_queue_create(const char *_Nullable label, dispatch_queue_attr_t _Nullable attr)
函數(shù)創(chuàng)建一個(gè)隊(duì)列對(duì)象码荔。
第一個(gè)參數(shù)表示隊(duì)列的唯一標(biāo)識(shí)符,第二個(gè)參數(shù)用于指定隊(duì)列是串行隊(duì)列(DISPATCH_QUEUE_SERIAL) 還是并發(fā)隊(duì)列(DISPATCH_QUEUE_CONCURRENT)感挥。
串行隊(duì)列的創(chuàng)建方法:
dispatch_queue_t queue = dispatch_queue_create("com.gcd.serail", DISPATCH_QUEUE_SERIAL);
并發(fā)隊(duì)列的創(chuàng)建方法:
dispatch_queue_t queue = dispatch_queue_create("com.gcd.concurrent", DISPATCH_QUEUE_CONCURRENT);
其它兩個(gè)隊(duì)列:
-
主隊(duì)列:主隊(duì)列負(fù)責(zé)在主線程上調(diào)度任務(wù)缩搅,如果主線程上已經(jīng)有任務(wù)在執(zhí)行,主隊(duì)列等待主線程上任務(wù)執(zhí)行完后在調(diào)度任務(wù)執(zhí)行触幼。
主隊(duì)列獲取方法:dispatch_queue_t mainQueue = dispatch_get_main_queue();
-
全局并發(fā)隊(duì)列:全局并發(fā)隊(duì)列是系統(tǒng)為了方便使用對(duì)線程硼瓣,提供的一個(gè)并發(fā)隊(duì)列。
全局并發(fā)隊(duì)列的獲取方法:dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
全局并發(fā)隊(duì)列獲取方法第一個(gè)參數(shù)表示隊(duì)列的優(yōu)先級(jí)置谦,第二個(gè)參數(shù)是擴(kuò)展位堂鲤,可以寫入任意值,沒有實(shí)際意義媒峡。
4瘟栖、同步、異步任務(wù)的創(chuàng)建方法
同步任務(wù):
同步任務(wù)創(chuàng)建函數(shù)如下:
dispatch_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block)
第一個(gè)參數(shù)為任務(wù)需要添加到的隊(duì)列谅阿,第二個(gè)參數(shù)為需要執(zhí)行的任務(wù)半哟。
同步任務(wù)不會(huì)開啟新的線程。
異步任務(wù):
異步任務(wù)創(chuàng)建函數(shù)如下:
dispatch_async(dispatch_queue_t queue, dispatch_block_t block)
第一個(gè)參數(shù)為任務(wù)需要添加到的隊(duì)列签餐,第二個(gè)參數(shù)為需要執(zhí)行的任務(wù)寓涨。
異步任務(wù)會(huì)開啟新的線程。
5贱田、GCD的使用方法
GCD的使用由多種隊(duì)列(主隊(duì)列缅茉、并發(fā)隊(duì)列、串行隊(duì)列)和兩種執(zhí)行方式(同步男摧、異步)進(jìn)行結(jié)合。因此有多種組合方式:
并發(fā)異步:
并發(fā)異步開啟多個(gè)線程译打,多任務(wù)交替執(zhí)行耗拓。
dispatch_queue_t queue = dispatch_queue_create("com.gcddemo.asyncconcurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"asyncIndex: 1-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"asyncIndex: 2-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
輸出結(jié)果:
2017-07-29 18:34:52.401 GCDDemo[22711:165644] asyncIndex: 1-0, currentThread: <NSThread: 0x60800007f400>{number = 3, name = (null)}
2017-07-29 18:34:52.401 GCDDemo[22711:165630] asyncIndex: 2-0, currentThread: <NSThread: 0x6000000754c0>{number = 4, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165644] asyncIndex: 1-1, currentThread: <NSThread: 0x60800007f400>{number = 3, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165630] asyncIndex: 2-1, currentThread: <NSThread: 0x6000000754c0>{number = 4, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165644] asyncIndex: 1-2, currentThread: <NSThread: 0x60800007f400>{number = 3, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165630] asyncIndex: 2-2, currentThread: <NSThread: 0x6000000754c0>{number = 4, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165644] asyncIndex: 1-3, currentThread: <NSThread: 0x60800007f400>{number = 3, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165630] asyncIndex: 2-3, currentThread: <NSThread: 0x6000000754c0>{number = 4, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165644] asyncIndex: 1-4, currentThread: <NSThread: 0x60800007f400>{number = 3, name = (null)}
2017-07-29 18:34:52.402 GCDDemo[22711:165630] asyncIndex: 2-4, currentThread: <NSThread: 0x6000000754c0>{number = 4, name = (null)}
從輸出結(jié)果上可以看出上述例子創(chuàng)建了兩個(gè)分線程,交替的執(zhí)行任務(wù)奏司。
并發(fā)同步:
任務(wù)按順序執(zhí)行乔询,不開啟新的線程。
dispatch_queue_t queue = dispatch_queue_create("com.gcddemo.syncconcurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"syncIndex: 1-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"syncIndex: 2-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
輸出結(jié)果:
2017-07-29 18:36:26.243 GCDDemo[22711:165589] syncIndex: 1-0, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.243 GCDDemo[22711:165589] syncIndex: 1-1, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.244 GCDDemo[22711:165589] syncIndex: 1-2, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.244 GCDDemo[22711:165589] syncIndex: 1-3, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.244 GCDDemo[22711:165589] syncIndex: 1-4, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.244 GCDDemo[22711:165589] syncIndex: 2-0, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.245 GCDDemo[22711:165589] syncIndex: 2-1, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.245 GCDDemo[22711:165589] syncIndex: 2-2, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.245 GCDDemo[22711:165589] syncIndex: 2-3, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
2017-07-29 18:36:26.245 GCDDemo[22711:165589] syncIndex: 2-4, currentThread: <NSThread: 0x600000072940>{number = 1, name = main}
輸出結(jié)果上可以看到當(dāng)前的線程為主線程韵洋,并沒有開啟新的線程竿刁,任務(wù)按先后順序執(zhí)行黄锤。
串行異步:
只開啟一條分線程,任務(wù)按照循序執(zhí)行食拜。
dispatch_queue_t queue = dispatch_queue_create("com.gdcdemo.asyncserail", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"asyncserialIndex: 1-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"asyncserialIndex: 2-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
輸出結(jié)果:
2017-07-29 18:41:29.923 GCDDemo[23359:171236] asyncserialIndex: 1-0, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.923 GCDDemo[23359:171236] asyncserialIndex: 1-1, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.923 GCDDemo[23359:171236] asyncserialIndex: 1-2, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.924 GCDDemo[23359:171236] asyncserialIndex: 1-3, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.924 GCDDemo[23359:171236] asyncserialIndex: 1-4, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.924 GCDDemo[23359:171236] asyncserialIndex: 2-0, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.924 GCDDemo[23359:171236] asyncserialIndex: 2-1, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.924 GCDDemo[23359:171236] asyncserialIndex: 2-2, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.924 GCDDemo[23359:171236] asyncserialIndex: 2-3, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
2017-07-29 18:41:29.925 GCDDemo[23359:171236] asyncserialIndex: 2-4, currentThread: <NSThread: 0x60000007cd00>{number = 3, name = (null)}
從輸出結(jié)果上可以看出鸵熟,上述例子值創(chuàng)建了一條分線程,任務(wù)按照先后循序執(zhí)行负甸。
串行同步:
任務(wù)按先后循序執(zhí)行流强,不開啟新的線程。
dispatch_queue_t queue = dispatch_queue_create("com.gcddemo.syncserail", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"syncserialIndex: 1-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"syncserialIndex: 2-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
輸出結(jié)果:
2017-07-29 18:47:04.147 GCDDemo[23910:176279] syncserialIndex: 1-0, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.147 GCDDemo[23910:176279] syncserialIndex: 1-1, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.147 GCDDemo[23910:176279] syncserialIndex: 1-2, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.147 GCDDemo[23910:176279] syncserialIndex: 1-3, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.148 GCDDemo[23910:176279] syncserialIndex: 1-4, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.148 GCDDemo[23910:176279] syncserialIndex: 2-0, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.148 GCDDemo[23910:176279] syncserialIndex: 2-1, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.148 GCDDemo[23910:176279] syncserialIndex: 2-2, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.148 GCDDemo[23910:176279] syncserialIndex: 2-3, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
2017-07-29 18:47:04.148 GCDDemo[23910:176279] syncserialIndex: 2-4, currentThread: <NSThread: 0x60000006c400>{number = 1, name = main}
從輸出結(jié)果上可以看出任務(wù)按照先后循序在主線程上執(zhí)行呻待,沒有開啟新的線程打月。
主隊(duì)列異步:
任務(wù)按先后順序在主線程中執(zhí)行。
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"asyncMianIndex: 1-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int index = 0; index < 5; index ++) {
NSLog(@"asyncMianIndex: 2-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
輸出結(jié)果:
2017-07-31 09:48:54.844 GCDDemo[7385:64936] asyncMianIndex: 1-0, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.844 GCDDemo[7385:64936] asyncMianIndex: 1-1, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.844 GCDDemo[7385:64936] asyncMianIndex: 1-2, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.844 GCDDemo[7385:64936] asyncMianIndex: 1-3, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.844 GCDDemo[7385:64936] asyncMianIndex: 1-4, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.845 GCDDemo[7385:64936] asyncMianIndex: 2-0, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.845 GCDDemo[7385:64936] asyncMianIndex: 2-1, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.845 GCDDemo[7385:64936] asyncMianIndex: 2-2, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.845 GCDDemo[7385:64936] asyncMianIndex: 2-3, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
2017-07-31 09:48:54.845 GCDDemo[7385:64936] asyncMianIndex: 2-4, currentThread: <NSThread: 0x608000261580>{number = 1, name = main}
從輸出結(jié)果可以去看出蚕捉,任務(wù)按照先后循序奏篙,在主線程上執(zhí)行。
主隊(duì)列同步:
在主隊(duì)列執(zhí)行同步任務(wù)時(shí)迫淹,由于任務(wù)之間相互等待报破,會(huì)造成崩潰。
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
for (int index = 0; index <= 10; index ++) {
NSLog(@"syncMainIndex: 1-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int index = 0; index <= 10; index ++) {
NSLog(@"syncMainIndex: 2-%d, currentThread: %@", index, [NSThread currentThread]);
}
});
代碼執(zhí)行的順序不是從上到下千绪,而是先執(zhí)行外部的代碼充易,發(fā)現(xiàn)有兩個(gè)同步任務(wù)加載到主隊(duì)列,立即去執(zhí)行兩個(gè)同步任務(wù)荸型,由于任務(wù)執(zhí)行需要等到另外一個(gè)任務(wù)執(zhí)行完才可以盹靴,兩個(gè)任務(wù)就相互等待,最終造成崩潰瑞妇。
上述總結(jié):
串行 | 并發(fā) | 主隊(duì)列 | |
---|---|---|---|
同步 | 不開啟新的線程 | 不開啟新的線程 | 線程崩潰 |
異步 | 開啟一條新的線程 | 開啟多條新的線程 | 不開啟新的線程稿静,在主線程執(zhí)行任務(wù) |
6、其他GCD函數(shù)
延時(shí)函數(shù):
GCD延時(shí)創(chuàng)建方法:
dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block)
第一個(gè)參數(shù)是延時(shí)的時(shí)間辕狰,第二參數(shù)是加載任務(wù)的隊(duì)列改备,第三個(gè)參數(shù)是延時(shí)結(jié)束后執(zhí)行的任務(wù)。
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
dispatch_after(time, queue, ^{
NSLog(@"after 3s, currentThread: %@", [NSThread currentThread]);
});
上述列子中創(chuàng)建了一個(gè)延時(shí)時(shí)間從當(dāng)前時(shí)間開始延時(shí)3秒蔓倍,將任務(wù)加載到最隊(duì)列中去悬钳,當(dāng)延時(shí)結(jié)束在主線程中執(zhí)行任務(wù)。
柵欄:
隊(duì)列加載柵欄函數(shù)攜帶的任務(wù)時(shí)偶翅,隊(duì)列中的其他任務(wù)要等待柵欄函數(shù)中的任務(wù)執(zhí)行結(jié)束才可以執(zhí)行默勾。
通過(guò)該功能可以實(shí)現(xiàn)不同線程任務(wù)執(zhí)行的先后順序以及實(shí)現(xiàn)鎖的功能。
柵欄函數(shù)不要放到主隊(duì)列以及全局并發(fā)隊(duì)列中聚谁。運(yùn)用柵欄函數(shù)一定要預(yù)防卡線程母剥。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSLog(@"berrier index 1, currentThread: %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"berrier index 2, currentThread: %@", [NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
NSLog(@"current thread: %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"berrier index 3, currentThread: %@", [NSThread currentThread]);
});
上述例子輸出結(jié)果:
2017-07-31 10:49:44.534 GCDDemo[12353:106669] berrier index 2, currentThread: <NSThread: 0x608000076bc0>{number = 7, name = (null)}
2017-07-31 10:49:44.534 GCDDemo[12353:113335] berrier index 1, currentThread: <NSThread: 0x60000006ba40>{number = 6, name = (null)}
2017-07-31 10:49:44.534 GCDDemo[12353:113336] current thread: <NSThread: 0x60000006edc0>{number = 8, name = (null)}
2017-07-31 10:49:44.534 GCDDemo[12353:113337] berrier index 3, currentThread: <NSThread: 0x600000078180>{number = 9, name = (null)}
輸出結(jié)果上可以看到開啟了多條新的線程,將任務(wù)分成兩組,第一組執(zhí)行結(jié)束后才執(zhí)行第二組任務(wù)环疼。
once函數(shù):
dispatch_once多用于單例的創(chuàng)建习霹,下屬代碼執(zhí)行一次后,再次執(zhí)行不會(huì)有l(wèi)og打印輸出炫隶。
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"once, current thread: %@", [NSThread currentThread]);
});
隊(duì)列組:
隊(duì)列組的創(chuàng)建方法如下:
dispatch_group_t group = dispatch_group_create()
隊(duì)列組是將加載任務(wù)的隊(duì)列放到隊(duì)列組中淋叶,當(dāng)隊(duì)列中的任務(wù)執(zhí)行完后,執(zhí)行如下方法:
dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block)
如合成網(wǎng)絡(luò)圖片及其他需要在分線程中工作等限,等待個(gè)線程完成工作后才執(zhí)行的任務(wù)爸吮。
__block int a = 0, b = 0, c = 0;
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
NSLog(@"dispath-group index: 1, current thread: %@", [NSThread currentThread]);
a = 1;
});
dispatch_group_async(group, queue, ^{
NSLog(@"dispath-group index: 2, current thread: %@", [NSThread currentThread]);
b = 3;
});
dispatch_group_async(group, queue, ^{
NSLog(@"dispath-group index: 3, current thread: %@", [NSThread currentThread]);
c = 5;
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"group-notify current thread: %@", [NSThread currentThread]);
NSLog(@"a + b + c = %d", a + b + c);
});
上述例子輸出結(jié)果如下:
2017-07-31 10:41:58.992 GCDDemo[12353:106684] dispath-group index: 1, current thread: <NSThread: 0x608000075ec0>{number = 3, name = (null)}
2017-07-31 10:41:58.992 GCDDemo[12353:106671] dispath-group index: 2, current thread: <NSThread: 0x608000075d80>{number = 4, name = (null)}
2017-07-31 10:41:58.992 GCDDemo[12353:106668] dispath-group index: 3, current thread: <NSThread: 0x608000075c00>{number = 5, name = (null)}
2017-07-31 10:41:58.993 GCDDemo[12353:106620] group-notify current thread: <NSThread: 0x600000066bc0>{number = 1, name = main}
2017-07-31 10:41:58.993 GCDDemo[12353:106620] a + b + c = 9
從輸出結(jié)果上可以看出對(duì)a、b望门、c的賦值分別是在不同的線程中完成的形娇,各個(gè)線程賦值結(jié)束后在回到主線程對(duì)a、b筹误、c進(jìn)行加法運(yùn)算桐早。
快速迭代:
快速迭代可以同時(shí)遍歷多個(gè)數(shù)字,多用于循環(huán)量特別大的操作中厨剪。如加載相冊(cè)圖片哄酝,當(dāng)圖片有上百?gòu)埖臅r(shí)候可能會(huì)造成卡頓現(xiàn)象,就可以使用快速迭代的方法祷膳。
dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
NSLog(@"apply index: %zu, current thread: %@", index, [NSThread currentThread]);
});
輸出結(jié)果如下:
2017-07-31 11:14:51.059 GCDDemo[12353:106620] apply index: 0, current thread: <NSThread: 0x600000066bc0>{number = 1, name = main}
2017-07-31 11:14:51.059 GCDDemo[12353:106669] apply index: 1, current thread: <NSThread: 0x608000076bc0>{number = 7, name = (null)}
2017-07-31 11:14:51.059 GCDDemo[12353:131416] apply index: 2, current thread: <NSThread: 0x608000077240>{number = 13, name = (null)}
2017-07-31 11:14:51.059 GCDDemo[12353:131417] apply index: 3, current thread: <NSThread: 0x608000077540>{number = 14, name = (null)}
2017-07-31 11:14:51.059 GCDDemo[12353:106620] apply index: 4, current thread: <NSThread: 0x600000066bc0>{number = 1, name = main}
2017-07-31 11:14:51.059 GCDDemo[12353:131416] apply index: 6, current thread: <NSThread: 0x608000077240>{number = 13, name = (null)}
2017-07-31 11:14:51.059 GCDDemo[12353:106669] apply index: 5, current thread: <NSThread: 0x608000076bc0>{number = 7, name = (null)}
2017-07-31 11:14:51.059 GCDDemo[12353:131417] apply index: 7, current thread: <NSThread: 0x608000077540>{number = 14, name = (null)}
2017-07-31 11:14:51.059 GCDDemo[12353:106620] apply index: 8, current thread: <NSThread: 0x600000066bc0>{number = 1, name = main}
2017-07-31 11:14:51.059 GCDDemo[12353:131416] apply index: 9, current thread: <NSThread: 0x608000077240>{number = 13, name = (null)}
從輸出結(jié)果上可以看出該函數(shù)開啟了多條新的線程陶衅,進(jìn)行數(shù)字的遍歷操作。
7直晨、總結(jié)
GCD的使用過(guò)程是指定任務(wù)的執(zhí)行方法(同步搀军、異步),并把任務(wù)添加到串行隊(duì)列或者并發(fā)隊(duì)列中勇皇,通過(guò)CPU調(diào)度執(zhí)行罩句。
上述只是GCD的基本使用方法,具體要結(jié)合使用環(huán)境敛摘,靈活運(yùn)用门烂。