iOS-GCD學(xué)習(xí)總結(jié)

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)用门烂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市兄淫,隨后出現(xiàn)的幾起案子屯远,更是在濱河造成了極大的恐慌,老刑警劉巖拖叙,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氓润,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡薯鳍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挖滤,“玉大人崩溪,你說(shuō)我怎么就攤上這事≌端桑” “怎么了伶唯?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)惧盹。 經(jīng)常有香客問(wèn)我乳幸,道長(zhǎng),這世上最難降的妖魔是什么钧椰? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任粹断,我火速辦了婚禮,結(jié)果婚禮上嫡霞,老公的妹妹穿的比我還像新娘瓶埋。我一直安慰自己,他們只是感情好诊沪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布养筒。 她就那樣靜靜地躺著,像睡著了一般端姚。 火紅的嫁衣襯著肌膚如雪晕粪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天渐裸,我揣著相機(jī)與錄音巫湘,去河邊找鬼。 笑死橄仆,一個(gè)胖子當(dāng)著我的面吹牛剩膘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播盆顾,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼怠褐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了您宪?” 一聲冷哼從身側(cè)響起奈懒,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宪巨,沒想到半個(gè)月后磷杏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捏卓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年极祸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遥金,死狀恐怖浴捆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稿械,我是刑警寧澤选泻,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站美莫,受9級(jí)特大地震影響页眯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厢呵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一窝撵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧述吸,春花似錦忿族、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至入撒,卻和暖如春隆豹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背茅逮。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工璃赡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人献雅。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓碉考,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親挺身。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侯谁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容