GCD基礎(chǔ)知識(shí)集合

GCD概念簡(jiǎn)單理解

GCD是基于C的Api弦聂。不需要自己管理線程生死鸟辅。只需要?jiǎng)?chuàng)建隊(duì)列,把任務(wù)放進(jìn)隊(duì)列里面就可以了莺葫》肆梗看上去很簡(jiǎn)單,其實(shí)也是有一段心酸路捺檬。
GCD有兩個(gè)核心概念再层。一個(gè)是任務(wù),一個(gè)是隊(duì)列。

同步函數(shù):在當(dāng)前線程中執(zhí)行聂受,不開啟新的線程
dispatch_sync(dispatch_queue_t queue, dispatch_block_tblock);

異步函數(shù):具備開啟線程的能力蒿秦。
dispatch_async(dispatch_queue_t queue, dispatch_block_tblock);

隊(duì)列

并發(fā)隊(duì)列
自動(dòng)開啟多個(gè)線程,并且可以讓多個(gè)任務(wù)同時(shí)執(zhí)行蛋济。
僅僅在異步函數(shù)(dispatch_async)下有效棍鳖。

串行隊(duì)列
讓線程一個(gè)接著一個(gè)的執(zhí)行。一條線程執(zhí)行完后再執(zhí)行下一條線程碗旅。

并發(fā)隊(duì)列

并發(fā)隊(duì)列不需要手動(dòng)創(chuàng)建渡处。以下是創(chuàng)建代碼。

dispatch_queue_tdispatch_get_global_queue(
dispatch_queue_priority_tpriority,// 隊(duì)列的優(yōu)先級(jí)
unsignedlongflags);// 此參數(shù)暫時(shí)無用扛芽,用0即可
dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//獲得全局并發(fā)隊(duì)列

全局并發(fā)隊(duì)列的優(yōu)先級(jí)
#defineDISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
#defineDISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(rèn)(中)
#defineDISPATCH_QUEUE_PRIORITY_LOW (-2)// 低
#defineDISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺(tái)
串行隊(duì)列
使用dispatch_queue_create函數(shù)創(chuàng)建串行隊(duì)列
dispatch_queue_t
dispatch_queue_create(constchar*label, //隊(duì)列名稱
dispatch_queue_attr_tattr);//隊(duì)列屬性骂蓖,一般用NULL即可
dispatch_queue_tqueue = dispatch_queue_create("isQueue", NULL);//創(chuàng)建
dispatch_release(queue);//非ARC時(shí)候需要釋放手動(dòng)創(chuàng)建的隊(duì)列

使用主隊(duì)列(跟主線程相關(guān)聯(lián)的隊(duì)列)
主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列
放在主隊(duì)列中的任務(wù),都會(huì)放到主線程中執(zhí)行
使用dispatch_get_main_queue()獲得主隊(duì)列
dispatch_queue_tqueue = dispatch_get_main_queue();

使用dispatch_sync同步函數(shù)時(shí)候川尖,在主線程中往主隊(duì)列添加任務(wù)會(huì)造成死鎖登下。

隊(duì)列與任務(wù)的結(jié)合
函數(shù) 全局并發(fā)隊(duì)列 手動(dòng)創(chuàng)建串行隊(duì)列 主隊(duì)列
同步 (sync) 沒有開啟新線程 串行執(zhí)行任務(wù) 沒有開啟新線程 串行執(zhí)行任務(wù) 沒有開啟新線程 串行執(zhí)行任務(wù)
異步 (async) 有開啟新線程 并發(fā)執(zhí)行任務(wù) 有開啟新線程 串行執(zhí)行任務(wù) 沒有開啟新線程 串行執(zhí)行任務(wù)
線程間的通訊

更新UI,數(shù)據(jù)等都是要回到主線程的。不能在子線程叮喳。

//獲取全局隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{

        NSLog(@"-子線程-- 開始下載圖片--%@",[NSThread currentThread]);

        //下載數(shù)據(jù)是耗時(shí)操作放到子線程
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/b219ebc4b74543a94369f4cb1c178a82b9011442.jpg"]]];

            dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"-主線程-- 刷新UI--%@",[NSThread currentThread]);
            //回到主線程刷新UI
            self.imageView.image = image;
        });
    });
延時(shí)操作

延時(shí)操作不會(huì)堵塞當(dāng)前線程.

//延遲操作
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)),//從什么時(shí)候開始被芳,是一個(gè)固定的算法
                   dispatch_get_main_queue(),//隊(duì)列
                   ^{
        //做要做的操作
    });
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

#pragma mark 延遲操作創(chuàng)建一
    //獲取全局隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //延時(shí)多久
    dispatch_time_t whenTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
    
    //延時(shí)操作,根據(jù)whenTime設(shè)計(jì)的時(shí)間
    dispatch_after(whenTime, queue, ^{
        NSLog(@"倒計(jì)時(shí)結(jié)束");
        
        dispatch_async(queue, ^{
            NSLog(@"-子線程-- 開始下載圖片--%@",[NSThread currentThread]);
            
            //下載數(shù)據(jù)是耗時(shí)操作放到子線程
            UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/b219ebc4b74543a94369f4cb1c178a82b9011442.jpg"]]];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"-主線程-- 刷新UI--%@",[NSThread currentThread]);
                
                //回到主線程刷新UI
                self.imageView.image = image;
                
            });
        });
    });
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    
#pragma mark 延遲操作創(chuàng)建二
    //獲取全局隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        NSLog(@"倒計(jì)時(shí)結(jié)束");
        
        dispatch_async(queue, ^{
            NSLog(@"-子線程-- 開始下載圖片--%@",[NSThread currentThread]);
            
            //下載數(shù)據(jù)是耗時(shí)操作放到子線程
            UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/b219ebc4b74543a94369f4cb1c178a82b9011442.jpg"]]];
            
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"-主線程-- 刷新UI--%@",[NSThread currentThread]);
                
                //回到主線程刷新UI
                self.imageView.image = image;
            });
        });
    });
GCD一次性代碼
static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
            //代碼只執(zhí)行一次
    });
});
GCD隊(duì)列組
分組模式 dispatch_group_notify

可以異步執(zhí)行多個(gè)耗時(shí)操作馍悟。等耗時(shí)操作都執(zhí)行完畢之后會(huì)回到主線程執(zhí)行操作畔濒。主要用于監(jiān)聽任務(wù)是否完成。

//獲取全局隊(duì)列
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //創(chuàng)建一個(gè)隊(duì)列組
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, globalQueue, ^{
        
        NSLog(@"--- 1 開始--- %@",[NSThread currentThread]);
        //延時(shí)5秒 模仿堵塞子線程
        [NSThread sleepForTimeInterval:5];
        NSLog(@"--- 2 --- 完成 %@",[NSThread currentThread]);
        
    });
    
    dispatch_group_async(group, globalQueue, ^{

        NSLog(@"--- 2 開始--- %@",[NSThread currentThread]);
        //延時(shí)5秒 模仿堵塞子線程
        [NSThread sleepForTimeInterval:5];
        NSLog(@"--- 2 --- 完成 %@",[NSThread currentThread]);
        
    });
    
    //在這個(gè)隊(duì)列組里面锣咒,會(huì)等group中的全部代碼執(zhí)行完畢再去執(zhí)行其它的操作
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        
        // 等前面的異步操作都執(zhí)行完畢后侵状,回到主線程...
        NSLog(@"全部完成");
        
    });

    //非ARC時(shí)候要釋放掉
    //dispatch_release(group);
dispatch_apply組內(nèi)無序循環(huán)執(zhí)行任務(wù)
//循環(huán)執(zhí)行任務(wù),并且執(zhí)行任務(wù)的順序是無序列的毅整。這里會(huì)堵塞當(dāng)前的線程趣兄。所以要注意。一般都是在子線程中執(zhí)行悼嫉。
dispatch_apply(size_t iterations,//執(zhí)行的次數(shù)
                   <#dispatch_queue_t queue#>,//隊(duì)列
                   <#^(size_t)block#>)//任務(wù)
    dispatch_apply(5, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
        NSLog(@"%zu",index);
    });
dispatch_set_target_queue 變更queue的優(yōu)先級(jí)別
dispatch_queue_t exampleQueue = dispatch_queue_create("com.example.queue", NULL);
    //設(shè)置這個(gè)全局并發(fā)隊(duì)列的優(yōu)先級(jí)為后臺(tái)
    dispatch_queue_t globalQueued = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_set_target_queue(exampleQueue, globalQueued);
    /**
     *  經(jīng)過轉(zhuǎn)換之后exampleQueue的優(yōu)先級(jí)別變成后臺(tái)
     */
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末艇潭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子戏蔑,更是在濱河造成了極大的恐慌蹋凝,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件总棵,死亡現(xiàn)場(chǎng)離奇詭異鳍寂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)情龄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門迄汛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來候味,“玉大人,你說我怎么就攤上這事隔心“兹海” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵硬霍,是天一觀的道長(zhǎng)帜慢。 經(jīng)常有香客問我,道長(zhǎng)唯卖,這世上最難降的妖魔是什么粱玲? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮拜轨,結(jié)果婚禮上抽减,老公的妹妹穿的比我還像新娘。我一直安慰自己橄碾,他們只是感情好卵沉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著法牲,像睡著了一般史汗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拒垃,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天停撞,我揣著相機(jī)與錄音,去河邊找鬼悼瓮。 笑死戈毒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的横堡。 我是一名探鬼主播埋市,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼翅萤!你這毒婦竟也來了恐疲?” 一聲冷哼從身側(cè)響起腊满,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤套么,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后碳蛋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胚泌,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年肃弟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玷室。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片零蓉。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖穷缤,靈堂內(nèi)的尸體忽然破棺而出敌蜂,到底是詐尸還是另有隱情,我是刑警寧澤津肛,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布章喉,位于F島的核電站,受9級(jí)特大地震影響身坐,放射性物質(zhì)發(fā)生泄漏秸脱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一部蛇、第九天 我趴在偏房一處隱蔽的房頂上張望摊唇。 院中可真熱鬧,春花似錦涯鲁、人聲如沸巷查。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吮便。三九已至,卻和暖如春幢踏,著一層夾襖步出監(jiān)牢的瞬間髓需,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工房蝉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留僚匆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓搭幻,卻偏偏與公主長(zhǎng)得像咧擂,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子檀蹋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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