GCD常用代碼(OC)

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é)果.

實例:創(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  默認
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)  低級
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后臺
ios8
QOS_CLASS_USER_INTERACTIVE 用戶希望線程快點執(zhí)行完畢,不要使用耗時操作
QOS_CLASS_USER_INITIATED 用戶需要的,不要使用耗時操作QOS_CLASS_DEFAULT 默認
QOS_CLASS_UTILITY 耗時操作
QOS_CLASS_BACKGROUND 后臺
QOS_CLASS_UNSPECIFIED 0 未指定優(yōu)先級

實例:

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)

實例:

dispatch_queue_t mainque = dispatch_get_main_queue();

線程之間的執(zhí)行順序:


同步執(zhí)行:
void
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

同步串行實例: 這里的代碼將 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因為是串行的所以會一個一個執(zhí)行,因為是同步執(zhí)行,所以在一個執(zhí)行完以前不會執(zhí)行下一個.并且不會開新線程.

串行同步.png
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ā)實例:這里的代碼將 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,雖然是并發(fā)隊列了,但是因為是同步執(zhí)行的原因,在一個代碼執(zhí)行完成之前,不能執(zhí)行另外一個任務(wù),所以仍然一個一個執(zhí)行,并且不會開啟新的線程.

并發(fā)同步.png
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í)行串行隊列實例: 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因為是異步執(zhí)行所以會再另開一條線程去執(zhí)行,而又因為是串行隊列,在一個任務(wù)執(zhí)行完成前不會執(zhí)行下一個所以只開1條線程,并且主線程繼續(xù)執(zhí)行.

異步執(zhí)行串行隊列.png
 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ā)隊列實例: 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因為是異步執(zhí)行所以會再另開一條線程去執(zhí)行,而又因為是并發(fā)隊列,在一個任務(wù)執(zhí)行完成前就會開一條新線程繼續(xù)執(zhí)行直到一個執(zhí)行完,會開幾條 新線程.

異步執(zhí)行并發(fā)隊列.png
dispatch_queue_t que = dispatch_queue_create("label", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0 ; i<10; i++) {
        dispatch_async(que, ^{
            NSLog(@"%@",[NSThread currentThread]);
        });
}

主線程的同步死鎖實例: 程序會卡主.主隊列在等待 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é)束");

主線程的異步實例:先執(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);

實例: 
// <#delayInSeconds#> 這里寫秒數(shù) 如3.0.
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)

完整實例:

 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)

實例:

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);

實例:

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);

實例:

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);

實例:

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);

實例

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

標(biāo)記: 進入組與離開組:

// 進入組的標(biāo)志
void
dispatch_group_enter(dispatch_group_t group);
// 離開組的標(biāo)志
void
dispatch_group_leave(dispatch_group_t group);

一個小實例

 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í)行否");

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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