iOS 多線程理解 - GCD篇

提及多線程 , 我們一定不會陌生 , 甚至線程問題已經(jīng)成為iOS 面試必問類型.
iOS 官方提供了 幾種多線程的解決方案 .

NSThread
GCD
NSOperation & NSOperationQueue

今天就 GCD(大調(diào)度中心) 的使用心得 進(jìn)行整理 . 剩下的以后慢慢補(bǔ)全.


基本術(shù)語

關(guān)鍵字 英文 解釋
串行 Serial 同一時間只能執(zhí)行一個任務(wù)
并發(fā) Concurrent 同一時間可以執(zhí)行多個任務(wù)
平行執(zhí)行 Parallelism 并發(fā)執(zhí)行的每一部分是被"同時執(zhí)行"的贫悄。
同步 Synchronous 按順序執(zhí)行 , 時效性是統(tǒng)一的.
異步 Asynchronous 可同時執(zhí)行 , 時效性不統(tǒng)一 .
危險區(qū) Critical Section 一段代碼不能并發(fā)執(zhí)行.并發(fā)操作共享資源時 , 該資源會損壞. (如數(shù)據(jù)NSMutableArray)
競態(tài)條件 Race Condition 多個進(jìn)程 , 對共享的數(shù)據(jù)進(jìn)行讀或?qū)懙牟僮鲿r , 由進(jìn)程的執(zhí)行順序不同而 導(dǎo)致結(jié)果的不同 .
死鎖 DeadLock 兩個線程進(jìn)入互相等待狀態(tài) , 及對方執(zhí)行完之后我再執(zhí)行 , 從而誰都無法執(zhí)行 , 形成死鎖.
線程安全 Thread Safe 同一段代碼 , 被多個線程同時執(zhí)行時, 不會造成數(shù)據(jù)損壞的代碼 是線程安全的代碼(如NSArray 是, NSMutableArray則不是.)
環(huán)境切換 Context Switch 在多個線程中 , 來回切換執(zhí)行曙寡,稱為環(huán)境切換筑舅。

==補(bǔ)充:==

1.競態(tài)條件 : 先檢測后執(zhí)行来累。執(zhí)行依賴于檢測的結(jié)果镊屎,而檢測結(jié)果依賴于多個線程的執(zhí)行時序,而多個線程的執(zhí)行時序通常情況下是不固定不可判斷的扩然,從而導(dǎo)致執(zhí)行結(jié)果出現(xiàn)各種問題珊楼。
例子:對于main線程,如果文件a不存在绪爸,則創(chuàng)建文件a湾碎,但是在判斷文件a不存在之后,Task線程創(chuàng)建了文件a奠货,這時候先前的判斷結(jié)果已經(jīng)失效介褥,(main線程的執(zhí)行依賴了一個錯誤的判斷結(jié)果)此時文件a已經(jīng)存在了,但是main線程還是會繼續(xù)創(chuàng)建文件a递惋,導(dǎo)致Task線程創(chuàng)建的文件a被覆蓋呻顽、文件中的內(nèi)容丟失等等問題.

隊列

GCD提供 dispatch queues 來操作代碼塊。這些隊列管理你提交給GCD的任務(wù)丹墨,并且按照FIFO(first input first output ,先入先出)順序執(zhí)行。

  • 串行隊列: 同一時間只能執(zhí)行一個任務(wù) , 沒有進(jìn)入到危險區(qū)的風(fēng)險,從而不能進(jìn)入競態(tài)條件.
  • 并發(fā)隊列: 可以同時執(zhí)行多個任務(wù) , 但執(zhí)行結(jié)束時間 , 無法預(yù)測.
  • 隊列類型:
    1. main queue(主線程) :串行隊列. 更新UI界面 , 只能在主線程進(jìn)行.
    2. Global Dispatch Queues :并發(fā)隊列 , 根據(jù)優(yōu)先級順序 分為(background , low , default , high).(蘋果API 用這些隊列).
    3. 自定義隊列
  • dispatch_async:異步分發(fā)任務(wù) , 使任務(wù)在后臺執(zhí)行嬉愧,從而不阻塞當(dāng)前線程贩挣。 例子: 向主線程分發(fā)任務(wù)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
        UIImage *overlayImage = [self faceOverlayImageFromImage:_image];
        dispatch_async(dispatch_get_main_queue(), ^{ 
            [self fadeInNewImage:overlayImage]; 
        });
    });

  • dispatch_after: 延遲執(zhí)行 dispatch_async ,如 延遲執(zhí)行 主隊列
double delayInSeconds = 1.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); // 1 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // 2 
        if (!count) {
            [self.navigationItem setPrompt:@"Add photos with faces to Googlyify them!"];
        } else {
            [self.navigationItem setPrompt:nil];
        }
    });
  • 單例的線程安全: 傳統(tǒng)方式創(chuàng)建單例 , 存在線程安全問題 . 如果連續(xù)多次調(diào)用此方法,有這樣一種可能没酣,線程A進(jìn)入if語句王财,在單例創(chuàng)建完成前,發(fā)生環(huán)境切換( context switch),轉(zhuǎn)到線程B裕便,線程B也會進(jìn)入if語句并實例化此單例绒净,然后系統(tǒng)再次環(huán)境切換到線程A,線程A會繼續(xù)執(zhí)行if語句后面的內(nèi)容偿衰,實例化另一個單例挂疆。這顯然就不是單例了.(兩個并發(fā)隊列 , 存在競態(tài)條件)
    • dispatch_once 當(dāng)一個線程已經(jīng)在執(zhí)行dispatch_once中的危險區(qū)(critical section),那另一個試圖進(jìn)入該代碼塊的線程將被阻止下翎,直到前一個線程執(zhí)行完畢危險區(qū)中的代碼缤言。
+ (instancetype)sharedManager
{
    static PhotoManager *sharedPhotoManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedPhotoManager = [[PhotoManager alloc] init];
        sharedPhotoManager->_photosArray = [NSMutableArray array];
    });
    return sharedPhotoManager;
}
  • dispatch_barrier_async : 可以通過此函數(shù) , 創(chuàng)建讀寫鎖. 當(dāng)它與并發(fā)隊列一起用時,它就像一個串行瓶頸视事。用barriers的API能確保提交的代碼塊是在特定時間指定隊列中唯一被執(zhí)行的胆萧。這意味著先前提交到此隊列中的代碼塊,要在dispatch barrier執(zhí)行前俐东,執(zhí)行完畢跌穗。
    • 一般用在自定義的并發(fā)隊列當(dāng)中.


      創(chuàng)建讀寫鎖

今天暫時分享到此 . 后續(xù)會繼續(xù)更新.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末订晌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蚌吸,更是在濱河造成了極大的恐慌锈拨,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件套利,死亡現(xiàn)場離奇詭異推励,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)肉迫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門验辞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喊衫,你說我怎么就攤上這事跌造。” “怎么了族购?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵壳贪,是天一觀的道長。 經(jīng)常有香客問我寝杖,道長违施,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任瑟幕,我火速辦了婚禮磕蒲,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘只盹。我一直安慰自己辣往,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布殖卑。 她就那樣靜靜地躺著站削,像睡著了一般。 火紅的嫁衣襯著肌膚如雪孵稽。 梳的紋絲不亂的頭發(fā)上许起,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音菩鲜,去河邊找鬼街氢。 笑死,一個胖子當(dāng)著我的面吹牛睦袖,可吹牛的內(nèi)容都是我干的珊肃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伦乔!你這毒婦竟也來了厉亏?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤烈和,失蹤者是張志新(化名)和其女友劉穎爱只,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體招刹,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡恬试,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疯暑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片训柴。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖妇拯,靈堂內(nèi)的尸體忽然破棺而出幻馁,到底是詐尸還是另有隱情,我是刑警寧澤越锈,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布仗嗦,位于F島的核電站,受9級特大地震影響甘凭,放射性物質(zhì)發(fā)生泄漏稀拐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一丹弱、第九天 我趴在偏房一處隱蔽的房頂上張望钩蚊。 院中可真熱鬧,春花似錦蹈矮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至踊东,卻和暖如春北滥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闸翅。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工再芋, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坚冀。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓济赎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子司训,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

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