1. 程式人生 > >iOS GCD淺談

iOS GCD淺談

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

  1. dispatch_queue_t bgQueue = myQueue; 
  2.    dispatch_async(dispatch_get_main_queue(), ^{ 
  3.        NSString *stringValue = [[[textField stringValue] copy] autorelease]; 
  4.        dispatch_async(bgQueue, ^{ 
  5.            // use stringValue in the background now
  6.        }); 
  7.    }); 

取決於你的需求,myQueue可以是使用者佇列也可以使全域性佇列。

不再使用鎖(Lock)

使用者佇列可以用於替代鎖來完成同步機制。在傳統多執行緒程式設計中,你可能有一個物件要被多個執行緒使用,你需要一個鎖來保護這個物件:

  1. NSLock *lock; 

訪問程式碼會像這樣:

  1. - (id)something 
  2.    { 
  3.        id localSomething; 
  4.        [lock lock]; 
  5.        localSomething = [[something retain] autorelease]; 
  6.        [lock unlock]; 
  7.        return localSomething; 
  8.    } 
  9.    - (void)setSomething:(id)newSomething 
  10.    { 
  11.        [lock lock]; 
  12.        if(newSomething != something) 
  13.        { 
  14.            [something release]; 
  15.            something = [newSomething retain]; 
  16.            [self updateSomethingCaches]; 
  17.        } 
  18.        [lock unlock]; 
  19.    } 

使用GCD,可以使用queue來替代:

  1. dispatch_queue_t queue; 

要用於同步機制,queue必須是一個使用者佇列,而非全域性佇列,所以使用usingdispatch_queue_create初始化一個。然後可以用dispatch_async 或者 dispatch_sync將共享資料的訪問程式碼封裝起來:

  1. - (id)something 
  2.     __block id localSomething; 
  3.     dispatch_sync(queue, ^{ 
  4.         localSomething = [something retain]; 
  5.     }); 
  6.     return [localSomething autorelease]; 
  7. - (void)setSomething:(id)newSomething 
  8.     dispatch_async(queue, ^{ 
  9.         if(newSomething != something) 
  10.         { 
  11.             [something release]; 
  12.             something = [newSomething retain]; 
  13.             [self updateSomethingCaches]; 
  14.         } 
  15.     });