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

實(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í)行下一個.并且不會開新線程.

串行同步.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ā)實(shí)例:這里的代碼將 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,雖然是并發(fā)隊列了,但是因?yàn)槭峭綀?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í)行串行隊列實(shí)例: 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因?yàn)槭钱惒綀?zhí)行所以會再另開一條線程去執(zhí)行,而又因?yàn)槭谴嘘犃?在一個任務(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ā)隊列實(shí)例: 封裝的代碼一個一個放入到que的隊列中去執(zhí)行,因?yàn)槭钱惒綀?zhí)行所以會再另開一條線程去執(zhí)行,而又因?yàn)槭遣l(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]);
        });
}

主線程的同步死鎖實(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í)行否");

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,699評論 2 370

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