29

蘋果的大中央調度參考說:爲什麼我應該選擇GCD over NSOperation並阻止高級應用程序?

」 ......如果你的應用需要在 系統 - 例如Unix的水平來操作,如果它需要操作文件描述符,馬赫 端口,信號,或定時器,GCD不限於系統級的應用程序,但在您將其用於更高級別的應用程序之前,您應該考慮Cocoa中提供的類似功能(通過 NS操作和塊對象)是否更容易使用或更多 適合您的需求。「

http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html

我能想到居然的情況下,對高層次應用,其中使用GCD的是強制性的,能/不應該使用的NSOperation。

有什麼想法?

+0

https:// cocoacasts。com /在nsoperation-and-grand-central-dispatch/ – Masih

回答

50

這裏所提出的觀點是同一個,克里斯·漢森在他的文章「When to use NSOperation vs. GCD」規定:

直截了當的答案是所有的應用程序 發展的一般準則:

始終使用您可以使用最高級別抽象,並在測量顯示它們需要 時將其下降到較低級別的抽象。

在這種特殊情況下,這意味着在編寫Cocoa 應用程序時,通常應該使用NSOperation,而不是使用GCD直接使用 。不是因爲效率上的差異,而是因爲NSOperation在GCD的機制之上提供了更高層次的抽象。

總的來說,我同意這一點。NSOperation和NSOperationQueue爲依賴和GCD塊和隊列沒有的一兩個其他事物提供支持,它們抽象出實現併發操作的底層細節。如果你需要這個功能,NSOperation是一個非常好的方法。

但是,在使用兩者後,我發現自己用GCD塊和隊列替換了所有基於NSOperation的代碼。我這樣做的原因有兩個:在使用NSOperation進行頻繁操作時會產生很大的開銷,並且我相信在使用GCD塊時我的代碼更清晰且更具描述性。

第一個原因來自我的應用程序中的分析,其中發現NSOperation對象分配和釋放過程在處理小而頻繁的操作時花費了大量CPU資源,例如將OpenGL ES框架渲染到屏幕上。 GCD塊完全消除了這種開銷,從而顯着提高了性能。

第二個原因更主觀,但我相信我的代碼比NSOperations更清晰。快速捕獲塊允許的範圍及其內聯屬性可以減少代碼,因爲您不需要創建自定義NSOperation子類或捆綁要傳入操作的參數,在我看來,描述性代碼更多,因爲您可以將代碼放在隊列中並在其被觸發的位置運行。

同樣,它是一個偏好問題,但我發現自己更多地使用GCD,即使在其他更抽象的Cocoa應用程序中。

+0

NSOperationQueue現在可以使用閉包。這個答案應該(略)更新嗎?另外,在過去的5年中,NSOperation是否有可能被優化以減少你發現的開銷? –

+0

我應該補充一點,我已經做了完全相反的事情 - 在多年直接使用GCD後,切換到NSOperationQueue是一片清新的空氣。我的「排隊」行爲現在已經很好定義,並且我可以完全控制最大併發操作。取消正在運行的操作並將其替換爲新操作也更容易,從而產生明確定義的行爲。我仍然使用GCD進行簡單的異步操作,但爲了滿足我的串行/異步排隊需求,我已切換到NSOperationQueue。 – strangetimes

+0

Upvoted很好的解釋。 – user3182143

4

好,的NSOperation沒有等同dispatch_source_t,dispatch_io,dispatch_data_t,dispatch_semaphore_t等..它也略高的開銷。

另一方面,libdispatch沒有等價於操作依賴關係,操作優先級(隊列優先級有些不同)或KVO操作。

+1

之間選擇'NSOperation'現在建立在'GCD'的頂部,所以除非你需要的東西不在另一箇中,這比另一方更有利於這一點。 – hypercrypt

+1

除了其他複雜性之外,它仍然需要對操作進行對象分配。對於非常細粒度的線程,實際上可能是一個有意義的開銷。是的,我測量了這一點;是的,這對我的一些代碼至關重要。 NSOperation對GCD的包裝根本不是人們可能期望的直接映射,因爲它需要支持依賴關係,KVO和優先級。 –

+0

他是對的,我還看到在使用NSOperation進行頻繁發生的操作時,我沒有看到GCD塊的顯着開銷。在這些情況下,對象分配/釋放可能非常昂貴,因此GCD可能更合適。 –

0

我其實剛剛讀過'關於這一點,而且,我相信它會來作爲知道驚喜,意見不同。

我不能想到一個情況,你必須使用GCD而不是NSOperation,但這並不意味着這種情況不存在。然而,我同意最佳實踐編碼的一般觀點:

如果您有一些適合工作的工具(在這種情況下,您已經擁有NSOperation與GCD塊),請使用具有最高抽象級別(即最高級別的API)的類。通常,使用/減少代碼通常更容易,您還可以從引入到更高級別API的潛在未來增強中獲益。

13
  • 首選GCD,其中任務並不複雜,最佳CPU性能是必需的。
  • 首選NSOperationQueue,其任務非常複雜,需要取消或暫停塊和依賴關係管理

GCD是一種輕量級的方式來表示要同時執行的工作單元。你不安排這些工作單位;系統會爲您安排時間安排。在塊之間添加依賴關係可能會讓人頭疼。作爲開發人員,取消或暫停塊可爲您創造額外的工作量!

與GCD相比,NSOperation和NSOperationQueue增加了一些額外開銷,但是您可以在各種操作之間添加依賴關係。您可以重新使用,取消或暫停操作。 NSOperation與Key-Value Observation(KVO)兼容;例如,您可以通過偵聽NSNotificationCenter來啓動NSOperation。

有關詳細說明,請參考這個問題:NSOperation vs Grand Central Dispatch

1

有兩件事情NSOperationQueue能做到這一點GCD沒有做:未成年一個是依賴(添加操作隊列,但它告訴只執行當某些其他操作完成時),最重要的是NSOperation爲您提供了一個可以在任務執行過程中接收消息的對象,與GCD不同,GCD具有無法接收消息但除非有限的方式。你要麼需要這兩個功能,要麼你不需要。如果你不這樣做,使用GCD只是一個非常容易使用。

這就是爲什麼NSOperation的有用示例總是非常複雜。如果他們很容易,你可以使用GCD代替。您通常會創建一個NSOperation的子類,這將是一些大量的工作,或者使用其他人創建的子類。

相關問題