IOS GCD使用指南

全稱:Grand Central Dispatch

簡介:GCD是對多線程、多核開發的比較完整的封裝。在使用GCD的時候,系統會自動根據CPU的使用情況進行調度,GCD是一個簡單易用,效果很好地多線程、多核開發工具。

dispatch_queue_t,GCD隊列

dispatch_async,異步操作。

dispatch_sync,同步操作。

dispatch_apply(,,) 。

dispatch_after(,,),延時。

dispatch_barrier_async(,);

dispatch_barrier_sync(,);

dispatch_queue_set_specific,就是向指定隊列里面設置一個標識。

dispatch_get_specific,就是在當前隊列中取出標識

dispatch_suspend/dispatch_resume

dispatch_once,一次執行。

Dispatch I/O,文件讀寫操作。

dispatch_block_t

dispatch_block_create(dispatch_block_flags_t flags, dispatch_block_t block);

dispatch_block_t

dispatch_block_create_with_qos_class(dispatch_block_flags_tflags,

dispatch_qos_class_tqos_class,intrelative_priority,

dispatch_block_t block);

一:dispatch_queue_t

? ? ? ? 系統本身有兩個隊列,dispatch_get_global_queue(,),全局隊列;dispatch_get_main_queue(),主隊列。同時,用戶可以自己創建隊列,dispatch_queue_create(,).

? ? ? ? 隊列的優先級,分高級、低級、默認和后臺,DISPATCH_QUEUE_PRIORITY_DEFAULT(0)為默認,DISPATCH_QUEUE_PRIORITY_HIGH(2)為高,DISPATCH_QUEUE_PRIORITY_LOW(-2)為低,DISPATCH_QUEUE_PRIORITY_BACKGROUND為后臺。

? ? ? ? dispatch_get_current_queue(void),得到當前隊列,只能作為調試手段,已被廢棄。

? ? ? ? 創建隊列時,存在兩種Dispatch Queue,一種是等待現在執行中處理的Serial Dispatch Queue,另一種是不等待現在執行中處理的Concurrent Dispatch Queue。避免數據競爭這種情況,用Serial Dispatch Queue。

生成Serial Dispatch Queue:

? ? ? ? dispatch_queue_t mySerialDispatchQueue =dispatch_queue_create("MySerialDispatchQueue",NULL);

生成ConcurrentDispatchQueue:

? ? ? ? dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("MyConcurrentDispatchQueue",DISPATCH_QUEUE_CONCURRENT);

? ? ? ? 兩種創建方式的區別是,create函數的第二個參數不一樣。

? ? ? ? 通過dispatch_queue_create函數生成的Dispatch Queue在使用結束后通過dispatch_release函數釋放dispatch_release(myConcurrentDispatchQueue);

? ? ? ? 其中,dispatch_get_main_queue()是Serial Dispatch Queue;dispatch_get_global_queue(,)是Concurrent Dispatch Queue。

二:dispatch_async

? ? ? ? 提交任務后立刻返回,在后臺隊列中執行提交的代碼塊。

? ? ? ? dispatch_async(,) 開啟一個異步操作,第一個參數是指定一個gcd隊列,第二個參數是分配一個處理事務的程序塊到該隊列。

? ? ? ? dispatch_async(dispatch_get_global(0,0),^{

? ? ? ? ? ? ? ? //處理耗時操作的代碼塊

? ? ? ? ? ? ? ? //處理完成,通知主線程刷新

? ? ? ? ? ? ? ? dispatch_async(dispatch_get_main_queue(),^{

? ? ? ? ? ? ? ? //回調,或者說是通知主線程刷新

? ? ? ? ? ? ? ? });

? ? ? ? });

? ? ? ? NSLog(@"");

? ? ? ? 提交任務后會立即執行log。

? ? ? ? 開發者只需要定義想執行的任務并追加到適當的Dispatch Queue 中,GCD就能生成必要的線程并計劃執行任務。所以,開發者操作的是隊列,系統會自己創建線程,管理線程。

三:dispatch_sync

? ? ? ? 提交完任務,等任務完成后才會返回。

? ? ? ? dispatch_sync(,) 開啟一個異步操作,第一個參數是指定一個gcd隊列,第二個參數是分配一個處理事務的程序塊到該隊列。

? ? ? ? 使用時會阻塞后續代碼執行,所以都沒有用的必要了。

四:dispatch_apply

? ? ? ? dispatch_apply類似一個for循環,會在指定的dispatch queue中運行block任務n次。dispatch_apply是一個同步調用,block任務執行n次后才返回。

實例:

? ? ? ? dispatch_apply(5,dispatch_get_global_queue(-2,0), ^(size_ti) {

? ? ? ? ? ? ? ? NSLog(@"%@我開始執行%zu times",[NSThreadcurrentThread],i+1);

? ? ? ? });

? ? ? ? NSLog(@"hello");

? ? ? ? 會順序打印1,2,3,4,5,然后打印hello。

? ? ? ? 如果放在dispatch_async中執行,打印順序未定。

? ? ? ? dispatch_async(dispatch_get_global_queue(0,0), ^{

? ? ? ? ? ? ? ? dispatch_apply(5,dispatch_get_global_queue(-2,0), ^(size_ti) {

? ? ? ? ? ? ? ? NSLog(@"%@我開始執行%zu times",[NSThreadcurrentThread],i+1);

? ? ? ? ? ? ? ? });

? ? ? ? });

? ? ? ? NSLog(@"hello");

? ? ? ? 會先打印hello,再打印數字。但打印的數字順序未定。


五:dispatch_after

? ? ? dispatch_after(,,)能把我們添加進隊列的任務延時執行,原理是在指定時間后追加任務處理到隊列中,并不是在指定時間后執行處理。該方法的第一個參數是時間dispatch_time_t,第二個參數是dispatch_queue,第三個參數是要執行的代碼塊。

? ? ? ? dispatch_time_t有兩種形式的構造方式,第一種相對時間:DISPATCH_TIME_NOW表示現在,NSEC_PER_SEC表示的是秒數,它還提供了NSEC_PER_MSEC表示毫秒第二種是絕對時間,通過dispatch_walltime函數來獲取,dispatch_walltime需要使用一個timespec的結構體來得到dispatch_time_t。


六:dispatch_barrier_async

? ? ? ? 將自己的任務插入到隊列之后,不會等待自己的任務結束,它會繼續把后面的任務插入到隊列,然后等待自己的任務結束后才執行后面任務。

實例:

? ? ? ? //1 創建并發隊列

? ? ? ? dispatch_queue_tconcurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

? ? ? ? //2 向隊列中添加任務

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"1,%@",[NSThread currentThread]);? ? });

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"2,%@",[NSThread currentThread]);? ? });

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"3,%@",[NSThread currentThread]);? ? });? ??

? ? ? ? dispatch_barrier_async(concurrentQueue, ^{? ? ? ? [NSThread sleepForTimeInterval:1.0];NSLog(@"barrier");? ? });

? ? ? ? NSLog(@"aa");

? ? ? ? ?dispatch_async(concurrentQueue, ^{NSLog(@"4,%@",[NSThreadcurrentThread]);? ? });

? ? ? ? NSLog(@"bb");

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"5,%@",[NSThreadcurrentThread]);? ? });

? ? ? ? 打印順序是:3,aa,1,2,bb,barrier,4,5。也就是說4,5的執行一定是在barrier的后面。

使用場景:

? ? ? ? 訪問數據庫使用,寫入操作。可以實現高效率的數據庫訪問和文件訪問。

七:dispatch_barrier_sync(,)

? ? ? ? 將自己的任務插入到隊列的時候,需要等待自己的任務結束之后才會繼續插入被寫在它后面的任務,然后執行它們。

? ? ? ? //1 創建并發隊列

? ? ? ? dispatch_queue_tconcurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

? ? ? ? //2 向隊列中添加任務

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"1,%@",[NSThread currentThread]);? ? });

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"2,%@",[NSThread currentThread]);? ? });

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"3,%@",[NSThread currentThread]);? ? });? ??

? ? ? ? dispatch_barrier_sync(concurrentQueue, ^{? ? ? ? [NSThread sleepForTimeInterval:1.0];NSLog(@"barrier");? ? });

? ? ? ? NSLog(@"aa");

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"4,%@",[NSThread currentThread]);? ? });

? ? ? ? NSLog(@"bb");

? ? ? ? dispatch_async(concurrentQueue, ^{NSLog(@"5,%@",[NSThreadcurrentThread]);? ? });

? ? ? ? 打印順序是:3,1,2,barrier,aa,bb,4,5。也就是說只有barrier執行了,后續的才會執行。

八:dispatch_queue_set_specific

? ? ? ? dispatch_queue_set_specific(queue, queueKey, &queueKey,NULL);

? ? ? ? 就是給queue隊列設置一個queueKey標識。

九:dispatch_get_specific

? ? ? ?dispatch_get_specific(key);

? ? ? ? 判斷當前隊列有無key標識。

實例:

? ? ? ? staticvoid* key =@"key111";

? ? ? ? dispatch_queue_set_specific(dispatch_get_global_queue(0,0),key, &key,NULL);

? ? ? ? if(dispatch_get_specific(key)) {

? ? ? ? ? ? ? ? NSLog(@"找到了標識隊列");

? ? ? ? }

? ? ? ? dispatch_async(dispatch_get_global_queue(0,0), ^{

? ? ? ? if(dispatch_get_specific(key)) {

? ? ? ? ? ? ? ? NSLog(@"找到了標識隊列1");

? ? ? ? }

? ? ? ? });

? ? ? ? 打印結果:找到了標識隊列1。

十:dispatch_suspend/dispatch_resume

? ? ? ? 當追加大量的處理到Dispatch Queue時,再追加處理的過程中,有時希望不執行已追加的處理,例如演算結果被Block截取時,一些處理會對這個演算結果造成影響。在這種情況下,只要掛起DispatchQueue即可,當可以執行時再恢復。

? ? ? ? dispatch_suspend(queue);掛起Dispatch Queue.

? ? ? ? dispatch_resume(queue);恢復指定的Dispatch Queue.

十一:dispatch_once

? ? ? ? 保證在應用程序執行中只執行一次指定處理的API。用來初始化。

? ? ? ? static dispatch_once_tpred;

? ? ? ? dispatch_once(&pred, ^{

? ? ? ? });

十二:Dispatch I/O

? ? ? ? 讀寫文件,提高文件讀取速度。

? ? ? ? pipe_q = dispatch_queue_create("PipeQ",NULL);

? ? ? ? pipe_channel = dispatch_io_create(DISPATCH_IO_STREAM, fd,pipe_q, ^(interror) {

? ? ? ? close(fd);

? ? ? ? });

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

推薦閱讀更多精彩內容