IOS GCD 的理解

GCD (Grand Central Dispatch) 是Apple公司開發的一種技術,它旨在優化多核環境中的併發操做並取代傳統多線程的編程模式。編程

在Mac OS X 10.6和IOS 4.0以後開始支持GCD。網絡

使用GCD的一個理由就是方便。回想一下之前的多線程編程,咱們會把異步調用的代碼放到另外的一個函數中,並經過NSThread開啓新線程來啓動這段代碼。 這種跳來跳去的流程對於複雜的邏輯簡直就是一場災難。更糟糕的是,調用線程時的環境對異步代碼是不可見的,若是咱們須要當時的臨時變量的話只有兩個選擇: 保存到類成員變量中或者做爲參數傳遞過去。前者會形成不少莫名奇妙的無關類成員,然後者的功能過於有限。多線程

GCD相對來講是一種更優雅的方式,看以下代碼:閉包

NSString* parameter = [self getSomeParameter];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSString* result = [self fetchResultFromWebWithParameter:parameter];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self updateUIWithResult:result];
    });
});

在上面的代碼中,出現了一種奇怪的格式:併發

^{code...}

解釋一下,當一段代碼被花括號包裹並在開頭放置上尖號時,咱們稱之爲塊(block)。若是你學過C語言的話(實際上,block正是apple對C的一個擴展), 你能夠認爲這是一個加強型的函數指針。它不只能夠當作一個變量來回傳遞,還能夠引用自己環境以外的變量(如上面代碼中的parameter)。 更進一步地說,它是apple的C擴展中閉包的實現。在block裏引用的對象會自動被retain,所以你也沒必要擔憂內存的問題。app

另外涉及到了三個函數異步

void dispatch_async(
    dispatch_queue_t queue,
    dispatch_block_t block);

dispatch_queue_t dispatch_get_global_queue(
    long priority,
    unsigned long flags); 

dispatch_get_main_queue();

dispatch_async 函數會將傳入的block塊放入指定的queue裏運行。這個函數是異步的,這就意味着它會當即返回而無論block是否運行結束。所以,咱們能夠在block裏運行各類耗時的操做(如網絡請求) 而同時不會阻塞UI線程。 
dispatch_get_global_queue 會獲取一個全局隊列,咱們姑且理解爲系統爲咱們開啓的一些全局線程。咱們用priority指定隊列的優先級,而flag做爲保留字段備用(通常爲0)。 
dispatch_get_main_queue 會返回主隊列,也就是UI隊列。它通常用於在其它隊列中異步完成了一些工做後,須要在UI隊列中更新界面(好比上面代碼中的[self updateUIWithResult:result])的狀況。async

好的,知道這些特性以後,咱們能夠這樣理解上面的代碼:利用parameter變量異步地發起一個網絡請求,並在請求以後更新UI線程。函數

相關文章
相關標籤/搜索