正在學習這塊的東西 轉載兩篇好文章 原文地址http://www.cnblogs.com/carlton/archive/2013/06/23/3150611.htmlhtml
概述api
直觀上理解,GCD偏向於系統級的API,也就是說它更接近於底層,在編寫規範的前提下它相較NSOperation的性能要略優。而Cocoa的異步框架即NSOperation相關提供的API,更偏向於應用層面,它是對系統底層調用(包括GCD等)的封裝,從功能層面上講相較GCD更爲豐富(NSOperation + Queue的形式具有一些GCD未直接包含的功能)併發
經過查閱官方文檔以及國外一些Blog的闡述,基本達成的共識是:在APP中,儘量的使用Cocoa,即high-level Api,除非在實際性能測試數據上發現不得不用更底層的api的時候,才進一步考慮使用GCD。app
而目前國內的開發者,大多數傾向於直接使用GCD,我想最主要的緣由是block思想接近於過程化,同時GCD書寫起來能更簡單隨意。框架
這裏引用兩段話:異步
GCD is not restricted to system-level applications, but before you use it for higher-level applications, you should consider whether similar functionality provided in Cocoa (via NSOperation and block objects) would be easier to use or more appropriate for your needs. See Concurrency Programming Guide for more information.
Always use the highest-level abstraction available to you, and drop down to lower-level abstractions when measurement shows that they are needed.
GCD - 1async
GCD從語言、運行時庫、系統擴展等三個方面給讓使用者更充分的操做多核設備,同時它基於隊列的概念,由於每個CPU core單位時間(時間片)內只能運行某個隊列的某個task,並經過優先級、FIFO等策略進行task的切換運行。ide
GCD共提供三種隊列形式:性能
1. main,即主線程,iOS的UI繪製、交互響應都要在此線程上執行學習
2. concurrent,併發線程隊列,task的進出隊列,都遵循FIFO策略,但隊列中的task‘看起來’是併發執行的完成時間卻多是以任意的順序結束。很容易理解,由於每一個task的執行時間長短一般不同。
3. serial,串行隊列,在此隊列中的task,one by one的執行,嚴格遵照FIFO
即,咱們要執行一個block(task),前提是須要知道咱們要將task放入哪一個或哪類(上述其中之一)queue?
1. 獲取一個GCD隊列
獲取GCD隊列的方法主要有如下幾種:
dispatch_queue_t dispatch_get_main_queue(void) - 獲取主線程隊列
dispatch_queue_t dispatch_get_global_queue(long priority,unsigned long flags) - 獲取全局隊列(該隊列是一個concurrent隊列)
dispatch_queue_t dispatch_queue_create(const char *label,dispatch_queue_attr_t attr) - 建立隊列,根據attr指定被建立的隊列的類型,能夠爲concurrent也能夠爲serial
2. 準備待執行的Block
dispatch_block_t ablock = ^(){ NSLog(@"Print in ##_queue @ ablock"); };
3. 將待執行的Task置於某個GCD隊列中執行
dispatch_block_t block_main = ^(){ NSLog(@"Print in main_queue @ block_main"); }; dispatch_queue_t main_queue = dispatch_get_main_queue(); dispatch_async(main_queue, block_main); // 將block_main置於main_queue中執行,async方法將馬上返回,block_main中的代碼將在這其中或隨後的某一時刻執行
dispatch_queue_t concurrent_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime,concurrent_queue, ^(void){
NSLog(@"This line will executed after 2s @ concurrent"); // 這裏用了concurrent隊列,若是爲main隊列,則效果等同:
//- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay
});
// 建立一個serial隊列 dispatch_queue_t serial_queue = dispatch_queue_create("SERIAL", DISPATCH_QUEUE_SERIAL); dispatch_async(serial_queue, ^(){ sleep(3); NSLog(@"block_1"); // 儘管爲異步調用且延遲3秒,但因爲在serial隊列中,block_1仍然先於block_2被打印出來 }); dispatch_async(serial_queue, ^(){ NSLog(@"block_2"); }); // 隊列在使用完畢以後必須進行release dispatch_release(serial_queue);
//由於在dispatch_async的時候,其實每一個block都對該隊列進行了retain,而起初咱們對其進行了create(也至關於retain),因此最後須要進行顯示的release。而對於main、concurrent隊列,就不能進行release了