IOS GCD的使用

1.什么是GCD

GCD 全程為 Grand Central Dispatch 是異步執(zhí)行任務(wù)的技術(shù)之一

2.Dispatch Queue

2.1 Serial Dispatch Queue
FIFO 先進(jìn)先出原則,等待現(xiàn)在執(zhí)行中的任務(wù)處理結(jié)束,是串行線程
2.2ConcurrentQueue
并行線程
2.3 Dispatch Queue的種類
Main Dispatch Queue(主線程執(zhí)行 串行隊(duì)列)
Global Dispatch Queue (High Priority 并行隊(duì)列 優(yōu)先級(jí)最高)
Global Dispatch Queue (Default Priority 并行隊(duì)列 優(yōu)先級(jí)默認(rèn))
Global Dispatch Queue (Low Priority 并行隊(duì)列 優(yōu)先級(jí)低)
Global Dispatch Queue (Background Priority 并行隊(duì)列 優(yōu)先級(jí)后臺(tái))
2.4 dispatch_set_target_queue
當(dāng)用dispatch_queue_create生成的dispatch queue需要改變執(zhí)行優(yōu)先級(jí)用到的函數(shù)
2.5 dispatch_after
延遲執(zhí)行處理,需要注意的是,dispatch_after 并不是在指定時(shí)間后執(zhí)行處理,而只是在指定時(shí)間追加處理到dispatch queue
2.6 dispatch_group
在單個(gè)線程中想要等線程結(jié)束之后執(zhí)行結(jié)束處理,這時(shí)候我們需要用到dispatch group 代碼如下

dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"block 1");
    });
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"block 2");
    });
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"block 3");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"block finish");
    });

輸出打印 block 1 2 3執(zhí)行順序不定,但是finish一定是最后輸出的
2.7 dispatch_barrier_async
在訪問(wèn)數(shù)據(jù)時(shí),用serial queue 我們可以避免數(shù)據(jù)競(jìng)爭(zhēng)的問(wèn)題,但是如果為了高效的對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀寫,我們需要引入concurrent dispatch queue,但是我們知道concurrent dispatch queue是并行線程,如果我們需要在讀取的線程內(nèi)添加寫的線程,這時(shí)候就會(huì)引發(fā)讀取與寫入的不符合,或者因?yàn)榉欠ㄔL問(wèn)導(dǎo)致異常結(jié)束,因此我們需要dispatch_barrier_async 看如下代碼

__block int readValue1 = 1;
    __block int readValue2 = 1;
    dispatch_queue_t conCurrentQueue = dispatch_queue_create("con_current_queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"block1 readValue1=%d,readValue2=%d",readValue1,readValue2);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"block2 readValue1=%d,readValue2=%d",readValue1,readValue2);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"block3 readValue1=%d,readValue2=%d",readValue1,readValue2);
    });
    dispatch_async(conCurrentQueue, ^{
        readValue1 = 2;
    });
    
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"block4 readValue1=%d,readValue2=%d",readValue1,readValue2);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"block5 readValue1=%d,readValue2=%d",readValue1,readValue2);
    });
    
    dispatch_barrier_async(conCurrentQueue, ^{
        readValue2 = 2;
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"block6 readValue1=%d,readValue2=%d",readValue1,readValue2);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"block7 readValue1=%d,readValue2=%d",readValue1,readValue2);
    });
/*
block1 readValue1=1,readValue2=1
block2 readValue1=1,readValue2=1
block4 readValue1=2,readValue2=1
block3 readValue1=2,readValue2=1
block5 readValue1=2,readValue2=1
block6 readValue1=2,readValue2=2
block7 readValue1=2,readValue2=2
*/

看打印 我們知道dispatch_barrier_async 是等前面的線程執(zhí)行完才去執(zhí)行,相當(dāng)于阻斷并行線程的作用
2.7 dispatch_apply
dispatch_apply 是dispatch_sync和dispatch_group的關(guān)聯(lián)API
2.8 dispatch_suspend /dispatch_resume
掛起某個(gè)線程和恢復(fù)某個(gè)線程
2.9 dispatch_semaphore
我們先看一段代碼

NSMutableArray *array = [[NSMutableArray alloc]init];
    for(int i=0;i<10000;i++){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            [array addObject:[NSNumber numberWithInt:i]];
        });
        
    }

該代碼由內(nèi)存錯(cuò)誤導(dǎo)致程序異常
dispatch_semaphore 使用計(jì)數(shù)來(lái)實(shí)現(xiàn)功能,當(dāng)計(jì)數(shù)為0時(shí)等待,當(dāng)計(jì)數(shù)為1或者大于1時(shí),減去1而不等待

NSMutableArray *array = [[NSMutableArray alloc]init];
    
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    for(int i=0;i<10000;i++){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //等待semaphore -1操作,相當(dāng)于線程阻塞
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            [array addObject:[NSNumber numberWithInt:i]];
           //semaphore +1操作
            dispatch_semaphore_signal(semaphore);
        });
        
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Grand Central Dispath(GCD):是iOS 4和OS X Snow Leopard 開(kāi)始引入的...
    明若晴空閱讀 1,249評(píng)論 0 0
  • 什么是GCD了解GCD前,需要了解的基礎(chǔ)知識(shí)GCD的使用使用注意事項(xiàng) -GCD學(xué)習(xí)前鋪墊-什么是GCDGCD (G...
    Hevin_Chen閱讀 706評(píng)論 1 1
  • dispatch_set_target_queue 我們發(fā)現(xiàn)獲取全局隊(duì)列時(shí),可以設(shè)置隊(duì)列的優(yōu)先級(jí),但是我們自己創(chuàng)建...
    沒(méi)腦子的程序員閱讀 765評(píng)論 0 1
  • iOS中GCD的使用小結(jié) 作者dullgrass 2015.11.20 09:41*字?jǐn)?shù) 4996閱讀 20199...
    DanDanC閱讀 1,272評(píng)論 0 0
  • 1.GCD的核心概念 GCD 核心概念:將任務(wù)添加到隊(duì)列,指定任務(wù)執(zhí)行的方法 任務(wù)使用block 封裝block ...
    CoderLWG閱讀 1,735評(píng)論 0 4

友情鏈接更多精彩內(nèi)容