iOS 多線程

iOS 多線程

GCD 深入理解:第一部分 作者:Derek Selander
GCD 深入理解:第二部分 作者:Derek Selander

一些常見的誤區

  • 并行 vs. 并發

多核設備通過并行來同時執行多個線程;然而,為了使單核設備也能實現這一點,它們必須先運行一個線程,執行一個上下文切換,然后運行另一個線程或進程。這通常發生地足夠快以致給我們并發執行地錯覺,如下圖所示
圖片
圖片
  • 串行 vs. 并發

任務串行執行就是每次只有一個任務被執行,任務并發執行就是在同一時間可以有多個任務被執行。

  • 同步 vs. 異步

一個同步函數只在完成了它預定的任務后才返回。一個異步函數,剛好相反,會立即返回,預定的任務會完成但不會等它完成。因此,一個異步函數不會阻塞當前線程去執行下一個函數。

**3種常見方式 **

1.NSThread

2.NSOperation

3. GCD

**dispatch_async **

自定義串行隊列:當你想串行執行后臺任務并追蹤它時就是一個好選擇。這消除了資源爭用,因為你知道一次只有一個任務在執行。注意若你需要來自某個方法的數據,你必須內聯另一個 Block 來找回它或考慮使用 dispatch_sync。主隊列(串行):這是在一個并發隊列上完成任務后更新 UI 的共同選擇。要這樣做,你將在一個 Block 內部編寫另一個 Block 。以及,如果你在主隊列調用 dispatch_async 到主隊列,你能確保這個新任務將在當前方法完成后的某個時間執行。并發隊列:這是在后臺執行非 UI 工作的共同選擇。

dispatch_after

自定義串行隊列:在一個自定義串行隊列上使用 dispatch_after 要小心。你最好堅持使用主隊列。主隊列(串行):是使用 dispatch_after 的好選擇;Xcode 提供了一個不錯的自動完成模版。并發隊列:在并發隊列上使用 dispatch_after 也要小心;你會這樣做就比較罕見。還是在主隊列做這些操作吧

dispatch_once

dispatch_once() 以線程安全的方式執行且僅執行其代碼塊一次。試圖訪問臨界區(即傳遞給 dispatch_once 的代碼)的不同的線程會在臨界區已有一個線程的情況下被阻塞,直到臨界區完成為止。

dispatch barriers

Dispatch barriers 是一組函數,在并發隊列上工作時扮演一個串行式的瓶頸。使用 GCD 的障礙(barrier)API 確保提交的 Block 在那個特定時間上是指定隊列上唯一被執行的條目。這就意味著所有的先于調度障礙提交到隊列的條目必能在這個 Block 執行前完成。當這個 Block 的時機到達,調度障礙執行這個 Block 并確保在那個時間里隊列不會執行任何其它 Block 。一旦完成,隊列就返回到它默認的實現狀態。 GCD 提供了同步和異步兩種障礙函數。下圖顯示了障礙函數對多個異步隊列的影響:

GCD 通過用 dispatch barriers 創建一個讀者寫者鎖 提供了一個優雅的解決方案。解決了 當一個線程調用讀方法 的同時另一個線程調用寫方法.即讀者寫者問題使用場合:自定義并發隊列

dispatch_sync

自定義串行隊列:在這個狀況下要非常小心!如果你正運行在一個隊列并調用 dispatch_sync 放在同一個隊列,那你就百分百地創建了一個死鎖。主隊列(串行):同上面的理由一樣,必須非常小心!這個狀況同樣有潛在的導致死鎖的情況。并發隊列:這才是做同步工作的好選擇,不論是通過調度障礙,或者需要等待一個任務完成才能執行進一步處理的情況。

一個例子 關于單例 讀寫者

// PhotoManager.m
// PhotoFilter//
// Created by A Magical Unicorn on A Sunday Night.// Copyright (c) 2014 Derek Selander. All rights reserved.//@import CoreImage;@import AssetsLibrary;
#import "PhotoManager.h"
@interface PhotoManager ()
@property (nonatomic, strong, readonly) NSMutableArray *photosArray;
@property (nonatomic, strong) dispatch_queue_t concurrentPhotoQueue;
@end
@implementation PhotoManager
// 單例類
+ (instancetype)sharedManager{ 
static PhotoManager *sharedPhotoManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ 
sharedPhotoManager = [[PhotoManager alloc] init]; 
sharedPhotoManager->_photosArray = [NSMutableArray array];  
sharedPhotoManager->_concurrentPhotoQueue = dispatch_queue_create("com.text", DISPATCH_QUEUE_CONCURRENT); }); return sharedPhotoManager;
}
// Getter And Setter
- (NSArray *)photos{
 __block NSArray *array;
 dispatch_sync(self.concurrentPhotoQueue, ^{ 
array = [NSArray arrayWithArray:_photosArray]; 
 });  
return array;}

- (void)addPhoto:(Photo *)photo{
 if (photo) { 
dispatch_barrier_async(self.concurrentPhotoQueue, ^{ 
[_photosArray addObject:photo]; 
dispatch_async(dispatch_get_main_queue(), ^{ 
[self postContentAddedNotification]; 
});; 
}); 
}}
@end

dispatch_group

Dispatch Group 會在整個組的任務都完成時通知你。這些任務可以是同步的,也可以是異步的,即便在不同的隊列也行。而且在整個組的任務都完成時,Dispatch Group 可以用同步的或者異步的方式通知你。因為要監控的任務在不同隊列,那就用一個 dispatch_group_t 的實例來記下這些不同的任務。當組中所有的事件都完成時,GCD 的 API 提供了兩種通知方式。第一種是 dispatch_group_wait ,它會阻塞當前線程,直到組里面所有的任務都完成或者等到某個超時發生。第二種是dispatch_group_notify> 自定義串行隊列:它很適合當一組任務完成時發出通知。主隊列(串行):它也很適合這樣的情況。但如果你要同步地等待所有工作地完成,那你就不應該使用它,因為你不能阻塞主線程。然而,異步模型是一個很有吸引力的能用于在幾個較長任務(例如網絡調用)完成后更新 UI 的方式。并發隊列:它也很適合 Dispatch Group 和完成時通知。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容

  • 本篇博客共分以下幾個模塊來介紹GCD的相關內容: 多線程相關概念 多線程編程技術的優缺點比較? GCD中的三種隊列...
    有夢想的老伯伯閱讀 1,027評論 0 4
  • 1. GCD簡介 iOS開發中多線程的API主要有pthread,NSThread,NSOperation和GCD...
    安東_Ace閱讀 1,281評論 0 6
  • 學習多線程,轉載兩篇大神的帖子,留著以后回顧!第一篇:關于iOS多線程,你看我就夠了 第二篇:GCD使用經驗與技巧...
    John_LS閱讀 631評論 0 3
  • 文/柒凌 1. 臺風過去了,一切又恢復了平靜。 傍晚的時候,許青川一個人坐在江邊。他并沒有在等人,也沒有在看風景。...
    柒凌閱讀 2,553評論 0 5
  • 文|悟恩居士圖|悟恩居士 前兩天有寫手加我微信,發文給我看文筆,我說文筆沒問題,如果要寫小說,就要學會設置情節了。...
    悟恩說事閱讀 1,715評論 1 10