上一篇講了一下GCD的基本用法,這一篇稍微升華一下,說說關於GCD編程中‘同步’的那些事兒。
先看一下原型:
-() asyncMethodForPrint:(NSString *-(*arr = [NSArray arrayWithObjects:,,,,,, (NSString *item
顯然上面是按a~g的順序進行日誌輸出,那麼對於一個多核行動裝置,充分利用起咱們的cpu的一種形式是什麼呢?當然是用GCD來弄了,通過GCD,通常系統自己維護一個work線程池,當有task需要被執行的時候,從線程池中‘拿’一個出來直接就能用,因此上面的代碼,在GCD編程的方式下,並發執行的形式為:
-() asyncMethodForPrint:(NSString *-(*arr = [NSArray arrayWithObjects:,,,,,, (NSString *item , ), ^
很簡單,至此,我們還是稍稍重複了上一篇所講的內容,當然,日誌不會再按順序輸出了,而是:
-- :: GCDExample[:-- :: GCDExample[-- :: GCDExample[:-- :: GCDExample[-- :: GCDExample[-- :: GCDExample[-- :: GCDExample[:] asyncMethodForPrint[g]
關於wait
那麼,現在問題來了,我們目前的任務僅僅是print一個個獨立無關聯的字串,當然可以通過concurrent隊列走並發的形式了,但如果業務變了,俺們需要在for迴圈後面列印asyncMethodForPrint方法執行的次數:
counter = -() asyncMethodForPrint:(NSString *++-(*arr = [NSArray arrayWithObjects:,,,,,, (NSString *item , ), ^
悲劇了,count列印的結果不是0,就是1 ,因為dispatch_async會立即返回。如何解決這個問題,思路是:輸出count之前,等待前面所有的task完結。那麼需要引入group的概念,
修改後代碼為:
counter = -() asyncMethodForPrint:(NSString * // 這裡主要還是為了引入group,更嚴謹些,需要引入dispatch_semaphore_signal NSLog(++-(*arr = [NSArray arrayWithObjects:,,,,,, dispatch_group_t group_1 = (NSString *item dispatch_group_async(group_1, dispatch_get_global_queue(, ), ^
就是他了,上面的代碼,如果瞭解分散式運算的同學,是不是感覺跟‘Map Reduce’相似?呵呵。
那麼,可以看到通過引入dispatch_group_t,能給我們帶來一些‘同步’的實現,相關的api還有dispatch_group_wait,請自行查閱Lib Doc。
GCD還有一些api,比如semaphore訊號量、dispatch source、非同步io等,平時用的機會也不是很多,暫不做深入學習,也許將來有篇GCD - 3那就說明真用到了。