2017-04-05 41 views
8

我深入瞭解併發性,並廣泛閱讀關於GCD和NSOperation。但是,很多帖子,比如canon answer on SO已經有幾年了。2017/Swift 3.1 - GCD vs NSOperation

這在我看來,NSOperation主要優勢曾經是,某些性能成本:

  • 「的路要走」,一般超過一個簡單的調度爲最高級別的抽象(之上構建的GCD)
  • 做任務操作(取消,等等)輕鬆很多
  • 輕鬆建立依賴性任務之間

由於GCD的DispatchWorkItem &塊取消/特別DispatchGroup/qos,是真的有一種激勵(性價比明智),以分開使用NSOperation了併發的,你需要能夠取消任務情況下,當它開始執行或查詢任務狀態?

蘋果似乎更重視GCD,至少在他們的WWDC(授予它比NSOperation更近)。

回答

4

我看到他們每個人仍然有自己的目的。我剛剛重新看了2015年WWDC關於這個(高級NSOperations)的討論,我在這裏看到兩個要點。

運行時間&用戶交互

從談話:

NSOperations運行一點點的時間比你所期望的一個塊的運行,所以塊通常需要幾納秒,也許最多一毫秒即可執行。

NSOperations,在另一方面,可以從幾毫秒更長,任何地方,甚至幾分鐘

他們談的是在WWDC app,其中存在一個的NSOperation的例子依賴於擁有登錄用戶。依賴項NSOperation提供了一個登錄視圖控制器並等待用戶進行身份驗證。一旦完成,該NSOperation完成,NSOperationQueue恢復工作。我認爲你不想在這種情況下使用GCD。

子類

由於NSOperations只是類,你可以繼承他們得到更多重用了出來。這對於GCD來說是不可能的。

例子:(從上面使用WWDC登錄的情況)

你在你的代碼庫很多NSOperations了與該要求他們進行身份驗證的用戶交互關聯。 (在這個例子中,喜歡視頻。)你可以擴展NSOperation來創建AuthenticatedOperation,然後讓所有這些NSOperations擴展這個新類。

1

首先,NSOperationQueue讓你排隊操作,也就是說,某種具有start法,cancel方法和一些可觀察性異步操作的,同時與調度隊列中的一個可以提交一個或一個關閉函數到一個調度隊列,然後將執行。

「操作」是比塊(或封閉件,功能)語義根本不同的。一個操作有一個底層的異步任務,而一個塊(閉包或函數)就是這樣。

什麼接近的NSOperation,雖然是一個異步功能,如:

func asyncTask(param: Param, completion: (T?, Error?) ->()) 

現在用期貨我們可以這樣定義同異步函數:

func asyncTask(param: Param) -> Future<T> 

這使得這種異步功能非常方便。

由於期貨有像mapflatMap等組合子功能,我們可以很容易地「模仿」的NSOperation「依賴」功能,只需在一個更強大,更簡潔,更易於理解的方式。

我們也可以實現某種NSOperationQueue與僅基於GCD基礎的幾行代碼,說「任務隊列」,並使用基本相同的功能,如「maxConcurrentTasks」,可以用它來排隊任務功能(而不是操作),只是一種更強大,更簡潔,更易理解的方式。 ;)

爲了獲得可取消操作,您需要創建NSOperation的子類 - 而您可以創建異步函數「ad-hod」 - 內聯。

此外,由於取消是一個獨立的概念,我們可以假設,存在一些庫,其實現完全基於GCD,它以通常的方式解決了這個問題;)可能看起來像這樣:

self.cancellationRequest = CancellationRequest() 
self.asyncTask(param: param, cancellationToken: cr.token).map { result in 
    ... 
} 

及更高版本:

override func viewWillDisappear(_ animated: animated) { 
    super.viewWillDisappear(animated) 
    self.cancellationRequest.cancel() 
} 

因此,恕我直言,真的沒有理由使用笨重NSOperationNSOperationQueue,而且也沒有任何理由更多的子類NSOperation,這是相當複雜和令人驚訝的困難,除非你不關心數據競賽。