本條要點:(做者總結)算法
GCD 技術確實很棒,不過有時侯採用標準系統庫的組件,效果會更好。必定要了解每項技巧的使用時機,若是選錯了工具,那麼編出來的代碼就會難於維護。服務器
不多有其餘技術能與GCD 的同步機制相媲美。對於那些只須要執行一次的代碼來講,也是如此,使用 GCD 的 dispatch_once 最爲方便。然而,在執行後臺任務時,GCD 並不必定是最佳方式。還有一種技術叫作 NSOperationQueue,它雖然與 GCD 不一樣,可是卻與之相關,開發者能夠把操做以 NSOperation 子類的形式放在隊列中,而這些操做也可以併發執行。其與 GCD 派發隊列有類似之處,這並不是巧合。「操做隊列」(operation Queue)在 GCD 以前就有了,其中某些設計原理因操做隊列而流行,GCD 就是基於這些原理構建的。實際上,從 iOS 4 與 Mac OSX 10.6 開始,操做隊列在底層是用 GCD 來實現的。數據結構
在二者的諸多差異中,首先要注意:GCD 是純 C 的 API,而操做隊列則是 Objective-C 的對象。在 GCD 中,任務用塊來表示,而塊是個輕量級數據結構。與之相反,「操做」(operation)則是個更爲重量級的 Objective-C 對象。雖然說如此,但 GCD 並不老是最佳方案。有時候採用對象所帶來的開銷微乎其微,使用完整對象所帶來的好處反而大大超過其缺點。多線程
用 NSOperationQueue 類的 「addOperationWithBlock:」 方法搭配 NSBlockOperation 類來使用操做隊列,其語法與純 GCD 方式很是相似。使用 NSOperation 及 NSOperationQueue 的好處以下:架構
正如你們所見,操做隊列有不少地方賽過派發隊列。操做隊列提供了多種執行任務的方式,並且都是寫好了的,直接就能使用。開發者不用再編寫複雜的調度器,也不用本身來實現取消操做或指定操做優先級的功能,這些事情操做隊列都已經實現好了。併發
有一個 API 選用了操做隊列而非派發隊列,這就是 NSNotificationCenter ,開發者可經過其中的方法來註冊監聽器,以便在發生相關事件時獲得通知,而這個方法接受的參數是塊,不是選擇子。方法原型以下:工具
1 - (id)addObserverForName:(NSString *)name object:(id)object queue:(NSOperationQueue *)queue usingBlock:(void(^)(NSNotification *))block;
原本這個方法也能夠不使用操做隊列,而是把處理通知事件所用的塊安排在派發隊列裏。但實際上並無這麼作,其設計者顯然使用了高層的 Objective-C API。在這種狀況下,兩套方案的運行效率沒多大差距。設計這個方法的人可能不想使用派發隊列,由於那樣將依賴於 GCD,而這種依賴沒有必要,前面說過,塊自己和 GCD 無關,因此若是僅使用塊的話,就不會引入對 GCD 的依賴了。也有可能編寫這個方法的人想所有用 Objective-C 來描述,而不想使用純 C 的東西。性能
常常會有人說:應該儘量選用高層 API,只在確有必要時才求助於底層。筆者也贊成這個說法,但我並不盲從。某些功能確實能夠用高層的 Objective-C 方法來作,但這並不等於說它就必定比底層實現方案好。要想肯定哪一種方案更佳,最好仍是要測試一下性能。測試
ENDspa