獅子頭鎮樓編程
《Objective-C 高級編程》學習筆記2-Blocksbash
將應用程序中記述的線程管理用的代碼在系統級中實現。開發者只須要定義想要執行的任務並追加到適當的 Dispatch Queue 中,GCD就能生成必要的線程並計劃執行任務。async
dispatch_async(queue, ^{
/* * 想執行的任務 */
})複製代碼
該源碼使用 Block 語法「定義想執行的任務」,經過 dispatch_async
函數「追加」賦值在變量 queue
的「Dispatch Queue中」。函數
Dispatch Queue:執行處理的等待隊列。有兩種:oop
//建立串行隊列
dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("com.gcd.mySerialDispatchQueue", NULL);
dispatch_async(mySerialDispatchQueue, ^{
//在串行隊列中執行Block
});
//建立並行隊列
dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("com.gcd.myConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myConcurrentDispatchQueue, ^{
//在並行隊列中執行Block
});
複製代碼
這是系統標準提供的 Dispatch Queue
2.3.一、Main Dispatch Queue
post
主線程執行的的 Dispatch Queue,由於主線程只有一個,因此它必定是串行隊列
追加到 Main Dispatch Queue 的處理在主線程的 RunLoop 中執行。所以用戶界面的操做等一些必須在主線程中執行的處理追加到 Main Dispatch Queue 中使用。學習
2.3.二、Global Dispatch Queueui
是全部應用程序都可以使用的並行隊列,它有四個優先級。
///主隊列獲取
dispatch_queue_t mdq = dispatch_get_main_queue();
//全局隊列,執行優先級:高
dispatch_queue_t gdq_high = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
//全局隊列,執行優先級:中
dispatch_queue_t gdq_default = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//全局隊列,執行優先級:低
dispatch_queue_t gdq_low = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
//全局隊列,執行優先級:後臺
dispatch_queue_t gdq_background = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
複製代碼
dispatch_queue_create
函數生成的 Dispatch Queue
無論是 串行隊列 仍是 並行隊列,都使用與默認優先級 Global Dispatch Queue
相同執行優先級的線程。可以使用 dispatch_set_target_queue
函數變動 Dispatch Queue
的執行優先級。spa
可以使用 dispatch_after
執行指定時間後執行的處理。注意:dispatch_after
函數並非在指定時間後執行處理,而只是在指定時間追加處理到 Dispatch Queue
。線程
dispatch_time_t dt = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
dispatch_after(dt, dispatch_get_main_queue(), ^{
//執行操做的block
});複製代碼
在追加到 Dispatch Queue 中的多個處理所有結束後想執行結束處理的時候使用。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ NSLog(@"blk0"); });
dispatch_group_async(group, queue, ^{ NSLog(@"blk1"); });
dispatch_group_async(group, queue, ^{ NSLog(@"blk2"); });
dispatch_group_async(group, queue, ^{ NSLog(@"blk3"); });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"done"); });
複製代碼
dispatch_sync 使用不當會形成一個很嚴重的問題:死鎖。
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"同步任務在 %@ 執行", [NSThread currentThread]);
});
//一、主線程正在執行主隊列的任務;
//二、一個同步任務過來了,因而,主線程當即等待;
//三、同步任務在等主線程當前任務完成,然而主線程在等待這個同步任務執行;
//四、因而就形成了相互等待的狀況。
複製代碼
dispatch_once 函數是保證在應用程序執行中只執行以此指定處理的API。如初始化單例。
+ (instancetype)share {
static id instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
return instance;
}複製代碼
GCD 的 Dispatch Queue 很是方便,實現 GCD 須要: