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是一個輕量級的,不用有太多考慮,隨意使用。