29

Appleのグランドセントラルディスパッチ参照は言う:高レベルアプリケーションのためにNSOperationとブロックでGCDを選択するのはなぜですか?

」...あなたのアプリケーションがファイル記述子を操作する必要がある場合、 システム - 例えばのUnixのレベルで動作する必要がある場合、マッハ ポート、信号、またはタイマーGCDはシステムレベルの アプリケーションに限定されていませんが、より高いレベルのアプリケーションに使用する前に、 NSOperationおよびブロックオブジェクト経由で同様の機能を使用するかどうかを検討するか、またはあなたのニーズに合ったより多くの 。 "

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

私は実際の状況を考えることはできません

、高レベルのアプリケーションのために、ここでGCDの使用が必須であり、NSOperationを/使用するべきではありませんでした。

どのような考えですか?

+0

https:// cocoacasts。 – Masih

答えて

50

ポイントは、クリス・ハンソンは、彼の記事「When to use NSOperation vs. GCD」で述べているものと同じである:

簡単な答えは、すべてのアプリケーション 開発のための一般的なガイドラインである:

常に使用します測定に「 」が必要であることが示されている場合は、下位レベルの抽象度にまで下げてください( )。

このケースでは、Cocoa アプリケーションを記述するときには、一般にGFCを使用して ではなくNSOperationを使用する必要があります。効率の違いによるものではなく、 NSOperationはGCDの メカニズムの上位レベルの抽象化を提供するためです。

一般に、私はこれに同意します。NSOperationとNSOperationQueueは、依存関係と、GCDブロックやキューにはない1つか2つのものをサポートし、並行処理の実装方法の詳細を抽象化しています。あなたがその機能を必要とするなら、NSOperationは非常に良い方法です。

しかし、両方で作業した後、自分のNSOperationベースのコードをすべてGCDブロックとキューに置き換えることができました。私はこれを2つの理由で行っています:頻繁なアクションにNSOperationを使用するとかなりのオーバーヘッドがあります.GCDブロックを使用すると、コードがよりクリーンで説明力があると思います。

最初の理由は私のアプリケーションのプロファイリングにあります。そこでは、OpenGL ESフレームを画面にレンダリングするような、頻繁ではないアクションに対処する際に、NSOperationオブジェクトの割り当てと割り当て解除処理にかなりのCPUリソースが必要でした。 GCDブロックはそのオーバヘッドを完全に排除し、パフォーマンスを大幅に向上させました。

第2の理由はより主観的ですが、私はNSOperationsよりもブロックを使用すると自分のコードがより洗練されていると思います。カスタムNSOperationサブクラスを作成する必要はなく、オペレーションに渡すパラメータをバンドルする必要がなく、私の意見ではより記述的なコードを使用する必要がないため、ブロックで許可されるスコープの迅速な取得とそのインラインの性質により、なぜなら、実行されるコードは、実行されるポイントでキューに置くことができるからです。

また、それは好みの問題ですが、私は自分自身が他の抽象化されたCocoaアプリケーションであっても、GCDをより多く使用していることを発見しました。

+0

NSOperationQueueはクロージャを使用できるようになりました。この回答は(少し)更新されるべきですか?また、あなたが見つけたオーバーヘッドを減らすために過去5年間でNSOperationが最適化されている可能性はありますか? –

+0

私はGCDを直接使って何年もの間、NSOperationQueueに切り替えることは、新鮮な空気の息吹であった。私の 'キューイング'ビヘイビアは今ではよく定義されており、私は最大コンカレント操作を完全に制御しています。実行中の操作を取り消し、新しい操作で取り替えることも容易であり、その結果、明確な動作が得られます。シンプルな非同期操作にはまだGCDを使用していますが、シリアル/非同期のキューイングのニーズに合わせてNSOperationQueueに切り替えました。 – strangetimes

+0

良い説明のためにアップしました。 – user3182143

4

まあ、NSOperationにはdispatch_source_t、dispatch_io、dispatch_data_t、dispatch_semaphore_tなどと同等のものはありません。これはやや高いオーバーヘッドです。

libdispatchには、操作の依存関係、操作の優先順位(キューの優先順位が多少異なる)、操作上のKVOに相当するものはありません。

+1

'NSOperation'は' GCD'の上に構築されていますので、あなたが必要とするものがない限り、他にはありません。それは他のものよりもはるかに有利です。 – hypercrypt

+1

他の複雑さの中でも、操作のためにオブジェクトの割り当てが必要です。実際に意味のあるオーバーヘッドになる可能性のある非常に細かいスレッディングの場合はい、私はこれを測定しました。はい、それは私のコードのいくつかのために重要です。依存関係、KVO、および優先順位をサポートする必要があるため、NSOperationのGCDのラッピングはまったく単純なマッピングではありません。 –

+0

彼はそうです、NSOperationをGCDブロックでは見られないような頻繁なアクションに使用する際に、かなりのオーバーヘッドが見られました。そのような場合は、オブジェクトの割り当てや割り当て解除が非常に高価になる可能性があるため、GCDがより適切な場合があります。 –

0

私は実際にこれについてラウンドを読んでいますが、驚きを知っていると確信しています。意見は異なります。

NSOperation上でGCDを使用する必要があるとは思えませんが、そのような場合は存在しません。しかし、私はベストプラクティスのコーディングに関して一般的な感想に同意します:

ジョブに合ったツールが2つある場合(この場合、NSOperationとGCDブロックがあります)、最高レベルの抽象化レベル(つまり、最高レベルのAPI)を持つクラスです。通常は、コードの使用量を減らすだけでなく、コードを減らすだけでなく、上位レベルのAPIに導入される潜在的な将来の拡張機能も活用します。ここで行われて

13
  • GCDは、タスクがそれほど複雑ではなく、の最適CPUパフォーマンスが必要です。
  • タスクが複雑で、ブロックおよび依存関係管理をキャンセルまたは中断するが必要なNSOperationQueueを推奨します。

GCDは、並行して実行される作業単位を表す軽量な方法です。あなたはこれらの作業単位をスケジュールしません。あなたのためにシステムがスケジューリングを行います。ブロック間に依存関係を追加することは頭痛になる可能性があります。ブロックをキャンセルまたは一時停止すると、開発者として余分な作業ができます!

NSOperationとNSOperationQueueは、GCDに比べて少しオーバーヘッドを追加しますが、さまざまな操作の間で依存関係を追加できます。操作を再利用、キャンセル、中断することができます。 NSOperationはKey-Value Observation(KVO)と互換性があります。例えば、NSNotificationを聞いてNSOperationを起動させることができます。詳しい説明については

、この質問参照してください:NSOperationQueueはGCDは行っていないことを行うことができる2つのものがありますNSOperation vs Grand Central Dispatch

1

を:マイナー一つは依存関係が(キューに操作を追加しているだけ実行するように指示非常に限られた方法以外ではメッセージを受信できないブロックを持つGCDとは異なり、NSOperationはタスクの実行中にメッセージを受け取ることができるオブジェクトを提供します。あなたはこれらの2つの機能を必要とするか、そうではありません。そうしないと、GCDを使うのはずっと使いやすいです。

NSOperationの有用な例は、常に非常に複雑です。彼らが簡単だったら、代わりにGCDを使います。あなたは通常、NSOperationのサブクラスを作成します。これはかなりの量の作業になります。あるいは、他の人が作成したものを使用します。

関連する問題