Objective-C多線程之GCD

Grand Central Dispatch(GCD)是異步執(zhí)行任務(wù)的技術(shù)之一揣炕,一般將應(yīng)用程序中記述的線程管理用的代碼在系統(tǒng)級(jí)實(shí)現(xiàn)。開發(fā)者值需要定義想執(zhí)行的任務(wù)并追加到適當(dāng)?shù)腄ispatch Queue中债朵,GCD就生成必要的線程并計(jì)劃執(zhí)行任務(wù)子眶。由于線程管理是作為系統(tǒng)的一部分來實(shí)現(xiàn)的,因此可以統(tǒng)一管理序芦,也可以執(zhí)行任務(wù)臭杰,這樣就比以前用線程更有效率。
GCD使用舉例

dispatch_async(queue,^{
/*
* 長(zhǎng)時(shí)間處理任務(wù)(如AR圖像識(shí)別谚中,數(shù)據(jù)庫訪問等)
*/
 dispatch_async(dispatch_get_main_queue(),^{
   /*
   * 只在主線程執(zhí)行的任務(wù)渴杆,例如界面的更新
  */
});
});

GCD的API


Dispatch Queue

Dispatch Queue的種類 說明
Serial Dispatch Queue 串行線程
Concurrent Dispatch Queue 并行線程

dispatch queue是線程執(zhí)行處理的等待隊(duì)列,應(yīng)用程序通過dispatch_async等API將執(zhí)行的任務(wù)追加到Queue中藏杖。


一共存在兩種Dispatch Queue 将塑。

Dispatch Queue的種類 說明
Serial Dispatch Queue 串行線程
Concurrent Dispatch Queue 并行線程



當(dāng)隊(duì)列為serial類型時(shí),只有一個(gè)線程蝌麸,并且任務(wù)按照串行執(zhí)行点寥。
當(dāng)隊(duì)列為concurrent類型時(shí),不止一個(gè)線程来吩,任務(wù)是并發(fā)執(zhí)行敢辩。

獲取dispatch queue

使用dispathc_queue_create創(chuàng)建

使用GCD的API生成dispatch queue。

dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.test.MySerialDispatchQueu",NULL);

第一個(gè)參數(shù)代表線程的名字弟疆,第二個(gè)參數(shù)NULL代表使用serial dispatch queue也就是串行的隊(duì)列戚长,如果要使用concurrent dispatch queue需要傳入DISPATCH_QUEUE_CONCURRENT

Serial Dispatch Queue生成的數(shù)量應(yīng)該僅限于必須要使用的串行線程數(shù)量怠苔,例如更行數(shù)據(jù)庫時(shí)一個(gè)表生成一個(gè)同廉。因?yàn)槊可梢粋€(gè)Serial Dispatch Queue系統(tǒng)就會(huì)生成一條線程,造成內(nèi)存和時(shí)間的消耗柑司。
當(dāng)執(zhí)行不發(fā)生數(shù)據(jù)競(jìng)爭(zhēng)的問題的時(shí)迫肖,用Concurrent Dispatch Queue。不管生成多少個(gè)Concurrent Dispatch Queue攒驰,系統(tǒng)都能有效管理線程蟆湖,不會(huì)出現(xiàn)Serial Dispatch Queue的問題。

注意:使用dispathc_queue_create創(chuàng)建的線程使用結(jié)束后要進(jìn)行釋放

使用dispatch_release釋放:即Dispatch Queue 和 Objective-C的引用計(jì)數(shù)管理內(nèi)存一樣玻粪,需要使用dispatch_retaindispatch_release進(jìn)行內(nèi)存管理

dispatch_queue_t queue = dispatch_create("com.test.MyConcurrentDispatchQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue,^{NSLog(@"block on queue")});
dispatch_release(queue);

Block也會(huì)持有queue所以不用擔(dān)心在第三行之后隅津,queue對(duì)象銷毀,只有當(dāng)Block也執(zhí)行完了劲室,才會(huì)進(jìn)行回收內(nèi)存伦仍。

使用系統(tǒng)提供的線程隊(duì)列

不用特意生成線程,系統(tǒng)也會(huì)提供幾個(gè)線程供使用

  • Main Dispatch Queue:主線程很洋,只用一個(gè)
  • Global Dispatch Queue:供所有程序使用的concurrent dispatch queue,另外這些線程有四個(gè)優(yōu)先級(jí)
名稱 種類 說明
Main Dispatch Queue Serial Dispatch Queue 主線程執(zhí)行
Global Dispatch Queue(High Priority) Concurrent Dispatch queue 優(yōu)先級(jí)最高
Global Dispatch Queue(Default Priority) Concurrent Dispatch queue 默認(rèn)
Global Dispatch Queue(Low Priority) Concurrent Dispatch queue 優(yōu)先級(jí)低
Global Dispatch Queue(Background Priority) Concurrent Dispatch queue 后臺(tái)執(zhí)行
// main dispatch queue 獲取
dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();
// global dispatch queue (High Priority) 獲取
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);

使用系統(tǒng)提供的線程不需要自行進(jìn)行內(nèi)存管理呢铆。

更改使用dispatch_queue_create生成的queue的優(yōu)先級(jí)

使用dispatch_queue_create生成的queue的優(yōu)先級(jí)和默認(rèn)的Global Dispatch Queue相同,可以使用dispatch_set_target_queue來改變優(yōu)先級(jí)

Dispatch_after(做定時(shí)任務(wù))

比如3秒后處理一個(gè)任務(wù)

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,3ull*NSEC_PER_SEC);
dispatch_after(time,queue,^{
// 任務(wù)
});

注意蹲缠,這里的3秒是3秒后加入任務(wù)棺克,不是精確的3秒悠垛,任務(wù)開始的最短時(shí)間在3秒后,最長(zhǎng)在3秒加一個(gè)時(shí)間片娜谊。
3ull中的ull代表unsigned long long 無符號(hào)長(zhǎng)整型确买。

dispatch_group

  • 創(chuàng)建group
dispatch_group_t dispatch_group_create(void);
  • 給任務(wù)設(shè)置group
void dispatch_group_async(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);
  • group里的任務(wù)全部執(zhí)行完后執(zhí)行最后一個(gè)任務(wù)
dispatch_group_notify(group,dispatch_get_main_queue(),^{NSlog(@"done");});
  • 等待group完成
long dispatch_group_wait(dispatch_group_t group,dispatch_time_t timeout);

dispatch_barrier_async

在訪問數(shù)據(jù)庫或者文件的使用,如上所述纱皆,可以使用串行隊(duì)列來避免競(jìng)爭(zhēng)湾趾。
而讀取不會(huì)發(fā)生競(jìng)爭(zhēng)可以用并行線程。
也就是說派草,為了高效率地進(jìn)行訪問搀缠,讀取處理追加到Concurrent Dispatch Queue中,寫入處理在任一個(gè)讀取處理沒有執(zhí)行的狀態(tài)下近迁,追加到Serial Dispatch Queue中艺普。
這種情況可以使用dispatch_barrier_async來解決讀取的問題。

dispatch_sync

dispatch_async是異步執(zhí)行的鉴竭。
dispatch_sync是同步執(zhí)行的歧譬。

dispatch_suspend/dispatch_resume

掛起和恢復(fù)queue

信號(hào)量

  • 創(chuàng)建
dispatch_semaphore_t 
dispatch_semaphore_create(long value);
  • 觸發(fā)信號(hào)量
long dispatch_semaphore_signal(dispatch_samaphore_t dsema);   //成功后 value++
  • 等待信號(hào)量
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);  //成功后 value --
信號(hào)量value為1的時(shí)候 退化為普通的鎖
信號(hào)量value為0的時(shí)候
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市搏存,隨后出現(xiàn)的幾起案子瑰步,更是在濱河造成了極大的恐慌,老刑警劉巖璧眠,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缩焦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡责静,警方通過查閱死者的電腦和手機(jī)袁滥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泰演,“玉大人,你說我怎么就攤上這事葱轩∧阑溃” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵靴拱,是天一觀的道長(zhǎng)垃喊。 經(jīng)常有香客問我,道長(zhǎng)袜炕,這世上最難降的妖魔是什么本谜? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮偎窘,結(jié)果婚禮上乌助,老公的妹妹穿的比我還像新娘溜在。我一直安慰自己,他們只是感情好他托,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布掖肋。 她就那樣靜靜地躺著,像睡著了一般赏参。 火紅的嫁衣襯著肌膚如雪志笼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天把篓,我揣著相機(jī)與錄音纫溃,去河邊找鬼。 笑死韧掩,一個(gè)胖子當(dāng)著我的面吹牛紊浩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播揍很,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼郎楼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了窒悔?” 一聲冷哼從身側(cè)響起呜袁,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎简珠,沒想到半個(gè)月后阶界,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聋庵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年膘融,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祭玉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氧映。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖脱货,靈堂內(nèi)的尸體忽然破棺而出振峻,到底是詐尸還是另有隱情,我是刑警寧澤鸽斟,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布拔创,位于F島的核電站,受9級(jí)特大地震影響湾盗,放射性物質(zhì)發(fā)生泄漏伏蚊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一格粪、第九天 我趴在偏房一處隱蔽的房頂上張望躏吊。 院中可真熱鬧,春花似錦帐萎、人聲如沸比伏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赁项。三九已至,卻和暖如春澈段,著一層夾襖步出監(jiān)牢的瞬間悠菜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國打工败富, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悔醋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓兽叮,卻偏偏與公主長(zhǎng)得像芬骄,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鹦聪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354