2017-04-05 1 views
8

私は、より深い同時性のダイビングをしており、GCDとNSOperationについて広く読んでいます。しかし、キャノニックanswer on SOのような多くの投稿は数年前です。一般的に、最も高いレベルの抽象化(のような単純なディスパッチ以上も2017/Swift 3.1 - GCDとNSOperation

  • 「進むべき道」:それがために使用NSOperation主な利点、いくつかのパフォーマンスを犠牲にように私には思えた

  • は、タスク操作(取消など)
  • が簡単にタスク間の依存関係を設定するには簡単に多くのことを行うために)GCDの上に構築され

考えるとGCDのDispatchWorkItem &ブロック取り消し/特にDispatchGroup/qos、インセンティブ(賢明なコストパフォーマンス)それが実行開始したときにタスクをキャンセルできるようにする必要がある場合は別に同時実行のためにもうNSOperationを使用することが本当にありますかタスクの状態をクエリしますか?

アップル社は、少なくともWWDCでは(より最近ではNSOperationよりも)、GCDに重点を置いているようです。

答えて

4

私はそれらのそれぞれがまだ自分の目的を持っているのを見ています。私は最近、2015年のWWDCでこれについての話を再訪しました(Advanced NSOperations)。ここでは2つの大きなポイントがあります。話から

ランタイム&ユーザとの対話

NSOperationsが長いブロックは通常、多分、数ナノ秒を取るので、あなたが、実行するためのブロックを期待するよりも、少しのために実行実行には最大でも1ミリ秒です。

NSOperationsは、他の一方で、どこかミリ秒にしても、数分

のカップルから、彼らはについて話すの例では、そのNSOperationが存在WWDCアプリであるため、はるかに長くすることができログインしたユーザーがいることに依存しています。依存関係NSOperationはログインビューコントローラを提示し、ユーザが認証を待つ。終了すると、そのNSOperationは終了し、NSOperationQueueはその作業を再開します。このシナリオではGCDを使いたくないと思います。 NSOperationsは単なるクラスなので、あなたがそれらからより多くの再利用性を得るためにそれらをサブクラス化することができ

をサブクラス化

。これはGCDでは不可能です。

例:(上からWWDCログインのシナリオを使用して)

あなたは認証されるためにそれらを必要とするユーザーとの対話に関連付けられているあなたのコードベースで多くのNSOperationsを持っています。 (この例ではビデオが好きです。)NSOperationを拡張してAuthenticatedOperationを作成し、次にすべてのNSOperationsにこの新しいクラスを拡張させることができます。

1

まず第一に、NSOperationQueueディスパッチキューと1がブロックを提出することができますが、それは、start方法、cancel方法といくつかの観察可能な特性を持つ非同期操作のいくつかの並べ替えで、あなたは操作をエンキューしましょうかクロージャまたはファンクションをディスパッチキューに追加して実行します。

「操作」は、ブロック(またはクロージャ、関数)と意味的に基本的に異なります。操作には基本的な非同期タスクがありますが、ブロック(クロージャーまたは関数)はそれだけです。 NSOperationに近づく何

は、しかし、例えば、非同期機能である:

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

先物で我々は次のように同じ非同期関数を定義することができます。

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

このような非同期関数は非常に便利です。

先物ようにmapflatMapようコンビネータ機能を持っているので、我々は非常に簡単にちょうどより強力な、より簡潔で、より分かりやすい方法で、NSOperationの「依存」機能を「エミュレート」することができます。

は、我々はまた、GCDのみに基づいて数行のコードで NSOperationQueueのいくつかの並べ替えを実装することができ

は、「maxConcurrentTasks」のような「タスクキュー」と基本的に同じ機能を持つが、言うと(タスク機能をエンキューするためにそれを使用することができます操作ではなく)、より強力で、より簡潔で、より分かりやすい方法でもあります。 ;)

を解約操作を得るために、あなたはNSOperationのサブクラスを作成する必要があります - インライン - あなたは非同期機能「広告-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() 
} 

、実際に使用する理由はありませんIMHO不格好NSOperationNSOperationQueue、と理由サブクラス化のために、それ以上はありませんNSOperationこれは、データ競合を気にしない限り、非常に精巧で驚くほど難しいものです。