【多線程】GCD簡介

一娃胆、簡單介紹

1.什么是GCD?

全稱是Grand Central Dispatch等曼,可譯為“牛逼的中樞調(diào)度器”

純C語言里烦,提供了非常多強(qiáng)大的函數(shù)

2.GCD的優(yōu)勢

GCD是蘋果公司為多核的并行運(yùn)算提出的解決方案

GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核(比如雙核、四核)

GCD會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程禁谦、調(diào)度任務(wù)胁黑、銷毀線程)

程序員只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼

3.提示

(1)GCD存在于libdispatch.dylib這個(gè)庫中州泊,這個(gè)調(diào)度庫包含了GCD的所有的東西丧蘸,但任何IOS程序,默認(rèn)就加載了這個(gè)庫遥皂,在程序運(yùn)行的過程中會(huì)動(dòng)態(tài)的加載這個(gè)庫貌嫡,不需要我們手動(dòng)導(dǎo)入横辆。

點(diǎn)擊+a按鈕,可以導(dǎo)入框架。

image

(2)GCD是純C語言的扰付,因此我們在編寫GCD相關(guān)代碼的時(shí)候,面對的函數(shù)隙弛,而不是方法攘滩。

(3)GCD中的函數(shù)大多數(shù)都以dispatch開頭庭猩。

二、任務(wù)和隊(duì)列

GCD中有2個(gè)核心概念

(1)任務(wù):執(zhí)行什么操作

(2)隊(duì)列:用來存放任務(wù)

GCD的使用就2個(gè)步驟

(1)定制任務(wù)

(2)確定想做的事情

將任務(wù)添加到隊(duì)列中陈症,GCD會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出蔼水,放到對應(yīng)的線程中執(zhí)行

提示:任務(wù)的取出遵循隊(duì)列的FIFO原則:先進(jìn)先出,后進(jìn)后出

三录肯、執(zhí)行任務(wù)

1.GCD中有2個(gè)用來執(zhí)行任務(wù)的函數(shù)

說明:把右邊的參數(shù)(任務(wù))提交給左邊的參數(shù)(隊(duì)列)進(jìn)行執(zhí)行趴腋。

(1)用同步的方式執(zhí)行任務(wù) dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

參數(shù)說明:

queue:隊(duì)列

block:任務(wù)

(2)用異步的方式執(zhí)行任務(wù) dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

2.同步和異步的區(qū)別

同步:在當(dāng)前線程中執(zhí)行

異步:在另一條線程中執(zhí)行

四、隊(duì)列

1.隊(duì)列的類型

GCD的隊(duì)列可以分為2大類型

(1)并發(fā)隊(duì)列(Concurrent Dispatch Queue)

可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效

image

(2)串行隊(duì)列(Serial Dispatch Queue)

讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后论咏,再執(zhí)行下一個(gè)任務(wù))

image

2.補(bǔ)充說明

有4個(gè)術(shù)語比較容易混淆:同步优炬、異步、并發(fā)潘靖、串行

同步和異步?jīng)Q定了要不要開啟新的線程

同步:在當(dāng)前線程中執(zhí)行任務(wù)穿剖,不具備開啟新線程的能力

異步:在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力

并發(fā)和串行決定了任務(wù)的執(zhí)行方式

并發(fā):多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行

串行:一個(gè)任務(wù)執(zhí)行完畢后卦溢,再執(zhí)行下一個(gè)任務(wù)

3.串行隊(duì)列

GCD中獲得串行有2種途徑

(1)使用dispatch_queue_create函數(shù)創(chuàng)建串行隊(duì)列

dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr); // 隊(duì)列名稱糊余, 隊(duì)列屬性,一般用NULL即可

示例:

dispatch_queue_t queue = dispatch_queue_create("wendingding", NULL); // 創(chuàng)建

dispatch_release(queue); // 非ARC需要釋放手動(dòng)創(chuàng)建的隊(duì)列

(2)使用主隊(duì)列(跟主線程相關(guān)聯(lián)的隊(duì)列)

主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列,放在主隊(duì)列中的任務(wù)单寂,都會(huì)放到主線程中執(zhí)行

使用dispatch_get_main_queue()獲得主隊(duì)列

示例:

dispatch_queue_t queue = dispatch_get_main_queue();

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

GCD默認(rèn)已經(jīng)提供了全局的并發(fā)隊(duì)列贬芥,供整個(gè)應(yīng)用使用,不需要手動(dòng)創(chuàng)建

使用dispatch_get_global_queue函數(shù)獲得全局的并發(fā)隊(duì)列

dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority,unsigned long flags); // 此參數(shù)暫時(shí)無用宣决,用0即可

示例:

這個(gè)參數(shù)是留給以后用的蘸劈,暫時(shí)用不上,傳個(gè)0尊沸。

第一個(gè)參數(shù)為優(yōu)先級威沫,這里選擇默認(rèn)的。獲取一個(gè)全局的默認(rèn)優(yōu)先級的并發(fā)隊(duì)列洼专。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 獲得全局并發(fā)隊(duì)列

image

說明:全局并發(fā)隊(duì)列的優(yōu)先級

DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高

DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(rèn)(中)
DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺

5.各種隊(duì)列的執(zhí)行效果

五棒掠、代碼示例

(1)用異步函數(shù)往并發(fā)隊(duì)列中添加任務(wù)

9 #import "YYViewController.h"
10 
11 @interface YYViewController ()
12 
13 @end
14 
15 @implementation YYViewController
16 
17 - (void)viewDidLoad
18 {
19     [super viewDidLoad];
20     //1.獲得全局的并發(fā)隊(duì)列
21    dispatch_queue_t queue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
22     //2.添加任務(wù)到隊(duì)列中,就可以執(zhí)行任務(wù)
23     //異步函數(shù):具備開啟新線程的能力
24     dispatch_async(queue, ^{
25         NSLog(@"下載圖片1----%@",[NSThread currentThread]);
26     });
27     dispatch_async(queue, ^{
28         NSLog(@"下載圖片2----%@",[NSThread currentThread]);
29     });
30     dispatch_async(queue, ^{
31         NSLog(@"下載圖片2----%@",[NSThread currentThread]);
32     });
33 //打印主線程
34     NSLog(@"主線程----%@",[NSThread mainThread]);
35     
36 }
37 
38 @end

總結(jié):同時(shí)開啟三個(gè)子線程

(2)用異步函數(shù)往串行隊(duì)列中添加任務(wù)

9 #import "YYViewController.h"
10 
11 @interface YYViewController ()
12 
13 @end
14 
15 @implementation YYViewController
16 
17 - (void)viewDidLoad
18 {
19     [super viewDidLoad];
20     
21     //打印主線程
22     NSLog(@"主線程----%@",[NSThread mainThread]);
23     
24     //創(chuàng)建串行隊(duì)列
25     dispatch_queue_t  queue= dispatch_queue_create("wendingding", NULL);
26     //第一個(gè)參數(shù)為串行隊(duì)列的名稱屁商,是c語言的字符串
27     //第二個(gè)參數(shù)為隊(duì)列的屬性烟很,一般來說串行隊(duì)列不需要賦值任何屬性,所以通常傳空值(NULL)
28     
29     //2.添加任務(wù)到隊(duì)列中執(zhí)行
30     dispatch_async(queue, ^{
31         NSLog(@"下載圖片1----%@",[NSThread currentThread]);
32     });
33     dispatch_async(queue, ^{
34         NSLog(@"下載圖片2----%@",[NSThread currentThread]);
35     });
36     dispatch_async(queue, ^{
37         NSLog(@"下載圖片2----%@",[NSThread currentThread]);
38     });
39     
40     //3.釋放資源
41 //    dispatch_release(queue);
42 }
43 
44 @end

總結(jié):會(huì)開啟線程蜡镶,但是只開啟一個(gè)線程

(3)用同步函數(shù)往并發(fā)隊(duì)列中添加任務(wù)

 9 #import "YYViewController.h"
10 
11 @interface YYViewController ()
12 
13 @end
14 
15 @implementation YYViewController
16 /**
17  *  用同步函數(shù)往并發(fā)隊(duì)列中添加任務(wù)
18  */
19 - (void)viewDidLoad
20 {
21     [super viewDidLoad];
22     
23     //打印主線程
24     NSLog(@"主線程----%@",[NSThread mainThread]);
25     
26     //創(chuàng)建串行隊(duì)列
27     dispatch_queue_t  queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
28 
29     
30     //2.添加任務(wù)到隊(duì)列中執(zhí)行
31     dispatch_sync(queue, ^{
32         NSLog(@"下載圖片1----%@",[NSThread currentThread]);
33     });
34     dispatch_sync(queue, ^{
35         NSLog(@"下載圖片2----%@",[NSThread currentThread]);
36     });
37     dispatch_sync(queue, ^{
38         NSLog(@"下載圖片3----%@",[NSThread currentThread]);
39     });
40 }
41 
42 @end

總結(jié):不會(huì)開啟新的線程雾袱,并發(fā)隊(duì)列失去了并發(fā)的功能

(4)用同步函數(shù)往串行隊(duì)列中添加任務(wù)

 9 #import "YYViewController.h"
10 
11 @interface YYViewController ()
12 
13 @end
14 
15 @implementation YYViewController
16 
17 
18 /**
19  *用同步函數(shù)往串行隊(duì)列中添加任務(wù)
20  */
21 - (void)viewDidLoad
22 {
23     [super viewDidLoad];
24      NSLog(@"用同步函數(shù)往串行隊(duì)列中添加任務(wù)");
25     //打印主線程
26     NSLog(@"主線程----%@",[NSThread mainThread]);
27     
28     //創(chuàng)建串行隊(duì)列
29     dispatch_queue_t  queue= dispatch_queue_create("wendingding", NULL);
30     
31     //2.添加任務(wù)到隊(duì)列中執(zhí)行
32     dispatch_sync(queue, ^{
33         NSLog(@"下載圖片1----%@",[NSThread currentThread]);
34     });
35     dispatch_sync(queue, ^{
36         NSLog(@"下載圖片2----%@",[NSThread currentThread]);
37     });
38     dispatch_sync(queue, ^{
39         NSLog(@"下載圖片3----%@",[NSThread currentThread]);
40     });
41 }
42 
43 @end

總結(jié):不會(huì)開啟新的線程

(5)補(bǔ)充

補(bǔ)充:隊(duì)列名稱的作用:

將來調(diào)試的時(shí)候,可以看得出任務(wù)是在哪個(gè)隊(duì)列中執(zhí)行的官还。

(6)小結(jié)

說明:同步函數(shù)不具備開啟線程的能力芹橡,無論是什么隊(duì)列都不會(huì)開啟線程;異步函數(shù)具備開啟線程的能力妻枕,開啟幾條線程由隊(duì)列決定(串行隊(duì)列只會(huì)開啟一條新的線程僻族,并發(fā)隊(duì)列會(huì)開啟多條線程)粘驰。

同步函數(shù)

(1)并發(fā)隊(duì)列:不會(huì)開線程

(2)串行隊(duì)列:不會(huì)開線程

異步函數(shù)

(1)并發(fā)隊(duì)列:能開啟N條線程

(2)串行隊(duì)列:開啟1條線程

補(bǔ)充:

凡是函數(shù)中屡谐,各種函數(shù)名中帶有create\copy\new\retain等字眼述么,都需要在不需要使用這個(gè)數(shù)據(jù)的時(shí)候進(jìn)行release。

GCD的數(shù)據(jù)類型在ARC的環(huán)境下不需要再做release愕掏。

CF(core Foundation)的數(shù)據(jù)類型在ARC環(huán)境下還是需要做release度秘。

異步函數(shù)具備開線程的能力,但不一定會(huì)開線程

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饵撑,一起剝皮案震驚了整個(gè)濱河市剑梳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌滑潘,老刑警劉巖垢乙,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異语卤,居然都是意外死亡追逮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門粹舵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钮孵,“玉大人,你說我怎么就攤上這事眼滤“拖” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵诅需,是天一觀的道長漾唉。 經(jīng)常有香客問我,道長堰塌,這世上最難降的妖魔是什么赵刑? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮蔫仙,結(jié)果婚禮上料睛,老公的妹妹穿的比我還像新娘。我一直安慰自己摇邦,他們只是感情好恤煞,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著施籍,像睡著了一般居扒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丑慎,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天喜喂,我揣著相機(jī)與錄音瓤摧,去河邊找鬼。 笑死玉吁,一個(gè)胖子當(dāng)著我的面吹牛照弥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播进副,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼这揣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了影斑?” 一聲冷哼從身側(cè)響起给赞,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎矫户,沒想到半個(gè)月后片迅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡皆辽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年柑蛇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膳汪。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡唯蝶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出遗嗽,到底是詐尸還是另有隱情粘我,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布痹换,位于F島的核電站征字,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏娇豫。R本人自食惡果不足惜匙姜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冯痢。 院中可真熱鬧氮昧,春花似錦、人聲如沸浦楣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽振劳。三九已至椎组,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間历恐,已是汗流浹背寸癌。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工专筷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蒸苇。 一個(gè)月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓磷蛹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親填渠。 傳聞我的和親對象是個(gè)殘疾皇子弦聂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

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