Objective C - 多線程

在iOS中每個進程啟動后都會建立一個主線程(UI線程),這個線程是其他線程的父線程埃疫。由于在iOS中除了主線程帚湘,其他子線程是獨立于Cocoa Touch的哮针,所以只有主線程可以更新UI界面(新版iOS中锤窑,使用其他線程更新UI可能也能成功璧针,但是不推薦)。iOS中多線程使用并不復(fù)雜渊啰,關(guān)鍵是如何控制好各個線程的執(zhí)行順序探橱、處理好資源競爭問題。常用的多線程開發(fā)有三種方式:

1.NSThread

2.NSOperation

3.GCD

三種方式是隨著iOS的發(fā)展逐漸引入的绘证,所以相比而言后者比前者更加簡單易用隧膏,并且GCD也是目前蘋果官方比較推薦的方式(它充分利用了多核處理器的運算性能)。

GCD

Grand Central Dispatch (GCD)是Apple開發(fā)的一個多核編程的解決方法迈窟。在iOS4.0開始之后才能使用私植。GCD是一個替代諸如NSThread, NSOperationQueue, NSInvocationOperation等技術(shù)的很高效和強大的技術(shù)〖烧ぃ現(xiàn)在的iOS系統(tǒng)都升級到7了车酣,所以不用擔(dān)心該技術(shù)不能使用。

(一)NSThread的使用

優(yōu)點:NSThread 比其他兩個輕量級

缺點:需要自己管理線程的生命周期索绪,線程同步湖员。線程同步對數(shù)據(jù)的加鎖會有一定的系統(tǒng)開銷。

NSThread 有兩種直接創(chuàng)建方式:第一個是實例方法瑞驱,第二個是類方法娘摔。

第一種方式會直接創(chuàng)建線程并且開始運行線程;

第二種方式是先創(chuàng)建線程對象唤反,然后再運行線程操作凳寺,在運行線程操作前可以設(shè)置線程的優(yōu)先級等線程信息。

其他同步

我們可以使用指令 @synchronized 來簡化 NSLock的使用彤侍,這樣我們就不必顯示編寫創(chuàng)建NSLock,加鎖并解鎖相關(guān)代碼肠缨。還有其他的一些鎖對象,比如:循環(huán)鎖NSRecursiveLock盏阶,條件鎖NSConditionLock晒奕,分布式鎖NSDistributedLock等等,可以自己看官方文檔學(xué)習(xí)。

(二)Cocoa NSOperation的使用

Cocoa NSOperation

優(yōu)點:不需要關(guān)心線程管理脑慧,數(shù)據(jù)同步的事情魄眉,可以把精力放在自己需要執(zhí)行的操作上。

Cocoa operation 相關(guān)的類是 NSOperation 闷袒,NSOperationQueue坑律。

NSOperation是個抽象類,使用 NSOperation的方式有兩種囊骤,一種是用定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation脾歇。另一種是繼承NSOperation。

如何控制線程池中的線程數(shù)淘捡?

隊列里可以加入很多個NSOperation, 可以把NSOperationQueue看作一個線程池藕各,可往線程池中添加操作(NSOperation)到隊列中。線程池中的線程可看作消費者焦除,從隊列中取走操作激况,并執(zhí)行它。線程池中的線程數(shù)膘魄,也就是并發(fā)操作數(shù)乌逐。默認情況下是-1,-1表示沒有限制创葡,這樣會同時運行隊列中的全部的操作浙踢。

(三)GCD的介紹和使用

介紹:

Grand Central Dispatch 簡稱(GCD)是蘋果公司開發(fā)的技術(shù),以優(yōu)化的應(yīng)用程序支持多核心處理器和其他的對稱多處理系統(tǒng)的系統(tǒng)灿渴。這建立在任務(wù)并行執(zhí)行的線程池模式的基礎(chǔ)上的洛波。它首次發(fā)布在Mac OS X 10.6 ,iOS 4及以上也可用骚露。

通過 GCD蹬挤,開發(fā)者不用再直接跟線程打交道了,只需要向隊列中添加代碼塊即可棘幸,GCD 在后端管理著一個線程池焰扳。GCD 不僅決定著你的代碼塊將在哪個線程被執(zhí)行,它還根據(jù)可用的系統(tǒng)資源對這些線程進行管理误续。這樣可以將開發(fā)者從線程管理的工作中解放出來吨悍,通過集中的管理線程,來緩解大量線程被創(chuàng)建的問題蹋嵌。

GCD 帶來的另一個重要改變是育瓜,作為開發(fā)者可以將工作考慮為一個隊列,而不是一堆線程欣尼,這種并行的抽象模型更容易掌握和使用爆雹。

首先停蕉,系統(tǒng)提供給你一個叫做 主隊列(main queue) 的特殊隊列。和其它串行隊列一樣钙态,這個隊列中的任務(wù)一次只能執(zhí)行一個慧起。然而,它能保證所有的任務(wù)都在主線程執(zhí)行册倒,而主線程是唯一可用于更新 UI 的線程蚓挤。這個隊列就是用于發(fā)生消息給 UIView 或發(fā)送通知的。

系統(tǒng)同時提供給你好幾個并發(fā)隊列驻子。它們叫做 全局調(diào)度隊列(Global Dispatch Queues) 灿意。目前的四個全局隊列有著不同的優(yōu)先級:background、low崇呵、default 以及 high缤剧。要知道,Apple 的 API 也會使用這些隊列域慷,所以你添加的任何任務(wù)都不會是這些隊列中唯一的任務(wù)荒辕。

最后,你也可以創(chuàng)建自己的串行隊列或并發(fā)隊列犹褒。這就是說抵窒,至少有五個隊列任你處置:主隊列、四個全局調(diào)度隊列叠骑,再加上任何你自己創(chuàng)建的隊列李皇。

GCD相比其他多線程有哪些優(yōu)點?

GCD 能通過推遲昂貴計算任務(wù)并在后臺運行它們來改善你的應(yīng)用的響應(yīng)性能宙枷。

GCD 提供一個易于使用的并發(fā)模型而不僅僅只是鎖和線程掉房,以幫助我們避開并發(fā)陷阱。

GCD 具有在常見模式(例如單例)上用更高性能的原語優(yōu)化你的代碼的潛在能力朦拖。

GCD 會自動利用更多的CPU內(nèi)核(比如雙核圃阳、四核)

GCD術(shù)語

串行(Serial):讓任務(wù)一個接著一個地執(zhí)行(一個任務(wù)執(zhí)行完畢后厌衔,再執(zhí)行下一個任務(wù))

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

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

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

dispatch queue分為下面三種:

Serial:又稱為private dispatch queues睬隶,同時只執(zhí)行一個任務(wù)。Serial queue通常用于同步訪問特定的資源或數(shù)據(jù)页徐。當你創(chuàng)建多個Serial queue時苏潜,雖然它們各自是同步執(zhí)行的,但Serial queue與Serial queue之間是并發(fā)執(zhí)行的变勇。

Concurrent:又稱為global dispatch queue恤左,可以并發(fā)地執(zhí)行多個任務(wù)贴唇,但是執(zhí)行完成的順序是隨機的。

Main dispatch queue:它是全局可用的serial queue飞袋,它是在應(yīng)用程序主線程上執(zhí)行任務(wù)的戳气。

1、常用的方法dispatch_async

為了避免界面在處理耗時的操作時卡死巧鸭,比如讀取網(wǎng)絡(luò)數(shù)據(jù)瓶您,IO,數(shù)據(jù)庫讀寫等,我們會在另外一個線程中處理這些操作纲仍,然后通知主線程更新界面呀袱。用GCD實現(xiàn)這個流程的操作比前面介紹的NSThread? NSOperation的方法都要簡單。

系統(tǒng)給每一個應(yīng)用程序提供了三個concurrent dispatch queues郑叠。這三個并發(fā)調(diào)度隊列是全局的夜赵,它們只有優(yōu)先級的不同。因為是全局的乡革,我們不需要去創(chuàng)建油吭。我們只需要通過使用函數(shù)dispath_get_global_queue去得到隊列,如下:

dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

這里也用到了系統(tǒng)默認就有一個串行隊列main_queue:

dispatch_queue_t mainQ = dispatch_get_main_queue();

雖然dispatch queue是引用計數(shù)的對象署拟,但是以上兩個都是全局的隊列婉宰,不用retain或release。

2推穷、dispatch_group_async的使用

dispatch_group_async可以實現(xiàn)監(jiān)聽一組任務(wù)是否完成心包,完成后得到通知執(zhí)行其他的操作。這個方法很有用馒铃,比如你執(zhí)行三個下載任務(wù)娃殖,當三個任務(wù)都下載完成后你才通知dispatch_group_notify界面說完成的了议谷。dispatch_group_async是異步的方法炉爆,運行后可以看到打印結(jié)果罗捎。

3慈格、dispatch_barrier_async的使用

dispatch_barrier_async是在前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行,而且它后面的任務(wù)等它執(zhí)行完成之后才會執(zhí)行吮成。

4逼裆、dispatch_apply

執(zhí)行某個代碼片段N次郁稍。

總結(jié):

- NSThread是早期的多線程解決方案,實際上是把C語言的PThread線程管理代碼封裝成OC代碼胜宇。

- GCD是取代NSThread的多線程技術(shù),C語法+block财破。功能強大然评。

- NSOperationQueue是把GCD封裝為OC語法,額外比GCD增加了幾項新功能狈究。

* 最大線程并發(fā)數(shù)

* 取消隊列中的任務(wù)

* 暫停隊列中的任務(wù)

* 可以調(diào)整隊列中的任務(wù)執(zhí)行順序碗淌,通過優(yōu)先級

* 線程依賴

* NSOperationQueue支持KVO。 這就意味著你可以觀察任務(wù)的狀態(tài)屬性磅废。

但是NSOperationQueue的執(zhí)行效率沒有GCD高纳像,所以一半情況下,我們使用GCD來完成多線程操作拯勉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末竟趾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宫峦,更是在濱河造成了極大的恐慌岔帽,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件导绷,死亡現(xiàn)場離奇詭異犀勒,居然都是意外死亡,警方通過查閱死者的電腦和手機妥曲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門贾费,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人檐盟,你說我怎么就攤上這事褂萧。” “怎么了葵萎?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵导犹,是天一觀的道長。 經(jīng)常有香客問我陌宿,道長锡足,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任壳坪,我火速辦了婚禮,結(jié)果婚禮上掰烟,老公的妹妹穿的比我還像新娘爽蝴。我一直安慰自己沐批,他們只是感情好,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布蝎亚。 她就那樣靜靜地躺著九孩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪发框。 梳的紋絲不亂的頭發(fā)上躺彬,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機與錄音梅惯,去河邊找鬼宪拥。 笑死,一個胖子當著我的面吹牛铣减,可吹牛的內(nèi)容都是我干的她君。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼葫哗,長吁一口氣:“原來是場噩夢啊……” “哼缔刹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起劣针,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤校镐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后捺典,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灭翔,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年辣苏,在試婚紗的時候發(fā)現(xiàn)自己被綠了肝箱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡稀蟋,死狀恐怖煌张,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情退客,我是刑警寧澤骏融,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站萌狂,受9級特大地震影響档玻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜茫藏,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一误趴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧务傲,春花似錦凉当、人聲如沸枣申。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忠藤。三九已至,卻和暖如春楼雹,著一層夾襖步出監(jiān)牢的瞬間模孩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工贮缅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留榨咐,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓携悯,卻偏偏與公主長得像祭芦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子憔鬼,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

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