GCD-2 Queuing Tasks for Dispatch

weixin_33751566發表於2016-08-21

本文是本人自己辛苦翻譯的,請轉載的朋友註明,翻譯於Z.MJun的簡書 ,感謝!<翻譯不容易啊>


完成翻譯於2016年5月17日


Queuing Tasks for Dispatch執行佇列任務的方法

GCD提供和管理FIFO(先進先出)的佇列,應用可以提交Block物件任務。系統會在一個執行緒池裡執行和管理被提交Block的排程佇列。不能保證被製成一個執行任務的執行緒。GCD提供了三種不同的佇列

  • Main:任務都會在應用的主執行緒下串型執行。
  • Concurrent:任務會在FIFO裡按順序排隊,但是,會併發執行,而且完成時順序不一樣。
  • Serial:任務會一一在FIFO裡按順序執行。

系統會自動建立主排程佇列和關聯到應用的主執行緒上。應用使用以下三個排程Block之間的一個,唯一一個來提交到主執行緒。

  • 呼叫 dispatch_main
  • 呼叫UIApplicationMain (iOS) or NSApplicationMain (OS X)
  • 使用 CFRunLoopRef在主執行緒。

使用併發佇列來執行龐大的數字任務。GCD自動建立4個並行排程佇列(三個優先順序於IOS 5 或 OS X v10.7)。這些佇列是應用全域性的,但優先等級不同。應用可以通過dispatch_get_global_queue這個方法呼叫他們。因為這些佇列是全域性的,所以不需要給他們分配記憶體,而分配記憶體是被忽略的。在OS X v10.7及以上,IOS 4.3及以上,你可以在應用裡建立新的並行佇列。

在序列佇列裡執行任務是被預測的。這個一個很好的做法,為每個佇列確定一個明確的目的。如保護一個資源或者同步一個關鍵工程。應用必須明確的建立和管理序列佇列。這是很有必要的,但是要避免把他們當成並行佇列來同時執行任務。

Important

GCD是基於C的API,他不像一些高階語言一樣能捕捉異常。應用必須在使用排程前確保沒有任何異常出現。

本文是本人自己辛苦翻譯的,請轉載的朋友註明,翻譯於Z.MJun的CSDN的部落格 http://blog.csdn.net/Zheng_Paul,感謝!


完成翻譯於2016年5月17日


非同步事件 dispatch_async

  • 描述:在一個佇列裡非同步執行任務,並從Block返回結果。
  • 方法:void dispatch_async( dispatch_queue_t queue, dispatch_block_t block)
  • 引數:
    • queue 提交Block的佇列。佇列被保留,直到功能執行完畢。這個引數不能為NULL。
    • block Block提交給目標排程佇列。相應會執行Block_copyBlock_release方法。這個引數也不能為NULL
  • 這個方法是提交Block到一個排程佇列的基本機制。呼叫這個方法,總是在Block被提交後馬上返回,並且從不等待Block被呼叫。目標佇列決定了Block是序列或者並行呼叫。獨立的序列佇列相對於彼此並行處理。

非同步事件 dispatch_async_f

  • 描述:在一個佇列裡非同步執行一個應用預設的方法,並從Block返回結果。

  • 方法:void dispatch_async_f( dispatch_queue_t queue, void *context, dispatch_function_t work)

  • 引數:

    • queue 提交Block的佇列。佇列被保留,直到功能執行完畢。這個引數不能為NULL。
    • context 傳遞給work的引數
    • work 系統執行的方法。這個引數不能為NULL。
  • 這個方法是使用系統提供的函式來實現非同步排程。呼叫這個方法,Block會馬上返回,並且不會等待事件的執行。目標佇列決定了Block是序列或者並行呼叫。獨立的序列佇列相對於彼此並行處理。

同步事件 dispatch_sync

  • 描述:同步操作,提交一個Block到佇列裡,並且等待直到Block處理完畢。

  • 方法:void dispatch_sync( dispatch_queue_t queue, dispatch_block_t block)

  • 引數:

    • queue 提交Block的佇列。這個引數不能為NULL。
    • block Block提交給目標排程佇列。這個引數不能為NULL。
  • 同步執行佇列。和dispatch_async不同的是,這個方法在Block的執行完才會返回。相應這個方法和當前的佇列會進入鎖死模式。

dispatch_async不一樣的,block在目標函式上是不會保留。因為這個響應是同步執行的。另外,這個block不會使用Block_copy

作為一個進階,這個方法有時候會在當前執行緒上呼叫Block。

同步事件 dispatch_sync_f

  • 描述:在一個佇列裡同步執行一個應用預設的方法,並從Block返回結果。
  • 方法:void dispatch_sync_f( dispatch_queue_t queue, void *context, dispatch_function_t work)
  • 引數:
    • queue 提交Block的佇列。佇列被保留,直到功能執行完畢。這個引數不能為NULL。
    • context 傳遞給work的引數
    • work 系統執行的方法。這個引數不能為NULL。
  • 類似dispatch_sync

定時執行 dispatch_after

  • 描述:特定時間內執行Block。
  • 方法:void dispatch_after( dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block)
  • 引數:
    • when 這個使用的是dispatch_time或者 dispatch_walltime型別。
    • queue 傳入帶有Block的佇列,系統會保留這個Block,直到Block被執行。這個引數不能為NULL。
    • block 執行的Block。這個功能會執行一個Block_copyBlock_release。(因為被保留了,使用完要釋放)。這個引數不能為NULL。
  • 這個功能是在一個給定的時間後,執行傳入佇列裡面的Block。When引數你可已使用DISPATCH_TIME_NOW,但是沒有使用dispatch_async好。也可以是用自定義的DISPATCH_TIME_FOREVER

定時執行 dispatch_after_f

  • 描述:特定時間內執行系統提供的函式。
  • 方法:void dispatch_after_f( dispatch_time_t when, dispatch_queue_t queue, void *context, dispatch_function_t work)
  • 引數:
    • when 這個使用的是dispatch_time或者 dispatch_walltime型別。
    • queue 傳入帶有Block的佇列,系統會保留這個Block,直到Block被執行。這個引數不能為NULL。
    • context 傳給系統提供的函式的引數
    • work 目標佇列會執行的系統預設函式。context是這個函式的引數。這個引數不能為NULL。
    • 這個功能是在一個給定的時間後,執行系統的預設函式work
  • 這個功能是在一個給定的時間後,執行傳入佇列裡面的Block。When引數你可已使用DISPATCH_TIME_NOW,但是沒有使用dispatch_async好。也可以是用自定義的DISPATCH_TIME_FOREVER

多次呼叫 dispatch_apply

  • 描述:多次呼叫傳入排程佇列的Block。
  • 方法:void dispatch_apply( size_t iterations, dispatch_queue_t queue, void (^block)( size_t))
  • 引數:
    • iterations 執行次數。
    • queue 傳入帶有Block的佇列。這個引數不能為NULL。
    • block 傳入的指定型別的Block。這個引數不能為NULL。
  • 這個功能是多次執行一個Block,直到執行次數完畢後才會返回。如果這個目標佇列是dispatch_get_global_queue的並行佇列 ,這個Block可以被同時呼叫。並且這Block必須是 reentrant-safe(安全)的。在並行佇列中使用這個方法就相當於使用一個有效的並行迴圈。

多次呼叫 dispatch_apply_f

  • 描述:多次呼叫傳入排程佇列的系統預設方法。
  • 方法:void dispatch_apply_f( size_t iterations, dispatch_queue_t queue, void *context, void (*work)(void *, size_t))
  • 引數:
    • iterations 執行次數。
    • queue 傳入帶有Block的佇列。這個引數不能為NULL。
      • context 傳給系統提供的函式的引數
    • work 目標佇列會執行的系統預設函式。第一個傳入函式的引數是context,第二個是iterations。 這個引數不能為NULL。
  • 這個功能是多次執行一個系統預設函式,直到執行次數完畢後才會返回。如果這個目標佇列是dispatch_get_global_queue的並行佇列 ,這個Block可以被同時呼叫。並且這Block必須是 reentrant-safe(安全)的。在並行佇列中使用這個方法就相當於使用一個有效的並行迴圈。

一次呼叫 dispatch_once

  • 描述:在函式週期裡面只會唯一的呼叫一次。
  • 方法:void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block)
  • 引數:
    • predicate 傳入一個dispatch_once_t結構體,來判斷這個Block是否執行完畢。
    • block 只會執行一次的Block。
  • 這個功能比較適合使用在單例上。在使用這個方法先,總是會在Block裡面嘗試是否能使用初始化。
  • 如果多個執行緒同時響應他,這個方法會同步執行,直到Block完成。
  • 這個宣告必須使用在全域性變數或者靜態變數。如果使用在自動或者動態儲存下,包括OBJ-C的例項變數,都是不定義的。

一次呼叫 dispatch_once

  • 描述:在函式週期裡面只會唯一的呼叫一次。
  • 方法:void dispatch_once_f( dispatch_once_t *predicate, void *context, dispatch_function_t function)
  • 引數:
    • predicate 傳入一個dispatch_once_t結構體,來判斷這個Block是否執行完畢。
    • context 通過function傳入的引數。
    • function 目標佇列會執行的系統預設函式。傳入函式的引數是context。 這個引數不能為NULL。
  • 這個功能比較適合使用在單例上。在使用這個方法先,總是會在Block裡面嘗試是否能使用初始化。
  • 如果多個執行緒同時響應他,這個方法會同步執行,直到Block完成。
  • 這個宣告必須使用在全域性變數或者靜態變數。如果使用在自動或者動態儲存下,包括OBJ-C的例項變數,都是不定義的。

相關文章