iOS – GCD(多線程)簡單示例: – iPhone手機開發技術文章 iPhone軟體開發教學課程

1. 在n秒後在新線程裡執行某些操作。ps:定時器需要在新線程裡執行

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    //coding
});

2.在後臺執行某些操作:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // coding
 });

3.在主線程執行某些操作:ps:有時候在這裡面更新UI

dispatch_async(dispatch_get_main_queue(), ^{
      // coding
 });

4.執行某些需要長時間的操作:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    // coding
});

GCD中有三種隊列類型:
1.The main queue: 與主線程功能相同。實際上,提交至main queue的任務會在主線程中執行。main queue可以調用dispatch_get_main_queue()來獲得。因為main queue是與主線程相關的,所以這是一個串行隊列。
2.Global queues: 全局隊列是並發隊列,並由整個進程共享。進程中存在三個全局隊列:高、中(默認)、低、後臺四個優先級隊列。可以調用dispatch_get_global_queue函數傳入優先級來訪問隊列。優先級:

#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN

3.用戶隊列: 用戶隊列 (GCD並不這樣稱呼這種隊列, 但是沒有一個特定的名字來形容這種隊列,所以我們稱其為用戶隊列) 是用函數 dispatch_queue_create 創建的隊列. 這些隊列是串行的。正因為如此,它們可以用來完成同步機制, 有點像傳統線程中的mutex。

創建隊列
要使用用戶隊列,我們首先得創建一個。調用函數dispatch_queue_create就行瞭。函數的第一個參數是一個標簽,這純是為瞭debug。Apple建議我們使用倒置域名來命名隊列,比如“com.dreamingwish.subsystem.task”。這些名字會在崩潰日志中被顯示出來,也可以被調試器調用,這在調試中會很有用。第二個參數目前還不支持,傳入NULL就行瞭。
提交 Job
向一個隊列提交Job很簡單:調用dispatch_async函數,傳入一個隊列和一個block。隊列會在輪到這個block執行時執行這個block的代碼。下面的例子是一個在後臺執行一個巨長的任務:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       //coding
});

dispatch_async 函數會立即返回, block會在後臺異步執行。
當然,通常,任務完成時簡單地NSLog個消息不是個事兒。在典型的Cocoa程序中,你很有可能希望在任務完成時更新界面,這就意味著需要在主線程中執行一些代碼。你可以簡單地完成這個任務——使用嵌套的dispatch,在外層中執行後臺任務,在內層中將任務dispatch到main queue:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //coding
        dispatch_async(dispatch_get_main_queue(), ^{
              //coding
        });
});

還有一個函數叫dispatch_sync,它幹的事兒和dispatch_async相同,但是它會等待block中的代碼執行完成並返回。結合 __block類型修飾符,可以用來從執行中的block獲取一個值。例如,你可能有一段代碼在後臺執行,而它需要從界面控制層獲取一個值。那麼你可以使用dispatch_sync簡單辦到:

__block NSString *stringValue;
dispatch_sync(dispatch_get_main_queue(), ^{
        // coding
});
[stringValue autorelease];
// use stringValue in the background now

我們還可以使用更好的方法來完成這件事——使用更“異步”的風格。不同於取界面層的值時要阻塞後臺線程,你可以使用嵌套的block來中止後臺線程,然後從主線程中獲取值,然後再將後期處理提交至後臺線程:

    dispatch_queue_t bgQueue = myQueue;
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *stringValue = [[[textField stringValue] copy] autorelease];
        dispatch_async(bgQueue, ^{
            // use stringValue in the background now
        });
    });

取決於你的需求,myQueue可以是用戶隊列也可以使全局隊列。

Ps:dispatch queue是一個輕量級的,不用有太多考慮,隨意使用。

發佈留言