iOS用の並行プログラミングについて学んでいます。これまで、NSOperation
/NSOperationQueue
とについて読みましたGCD
。over を使用する理由とその逆の理由は何ですか?NSOperationQueue
GCD
両方のような音GCD
やNSOperationQueue
抽象化を明示的に作成するNSThreads
ユーザから。ただし、2つのアプローチの関係は明確ではないため、フィードバックをお待ちしています。
iOS用の並行プログラミングについて学んでいます。これまで、NSOperation
/NSOperationQueue
とについて読みましたGCD
。over を使用する理由とその逆の理由は何ですか?NSOperationQueue
GCD
両方のような音GCD
やNSOperationQueue
抽象化を明示的に作成するNSThreads
ユーザから。ただし、2つのアプローチの関係は明確ではないため、フィードバックをお待ちしています。
回答:
GCD
低レベルのCベースのAPIで、タスクベースの同時実行モデルを非常に簡単に使用できます。NSOperation
そして、NSOperationQueue
同様のことを行うObjective-Cのクラスです。NSOperation
が最初に導入されましたが、10.5およびiOS 2以降NSOperationQueue
、友人はを使用して内部的に実装されていGCD
ます。
一般に、ニーズに合った最高レベルの抽象化を使用する必要があります。これは、サポートしていないことを行う必要がない限り、通常のNSOperationQueue
代わりに使用する必要があることを意味します。GCD
NSOperationQueue
これNSOperationQueue
はGCDの「機能が低下した」バージョンではないことに注意してください。実際、NSOperationQueue
pureで多くの作業を行うことで、非常に簡単にできることがたくさんありGCD
ます。(例:一度にN個の操作しか実行しない、帯域幅に制約のあるキュー。操作間の依存関係を確立します。どちらも非常に単純でNSOperation
、非常に困難GCD
です。)Appleは、GCDを利用して非常に優れたオブジェクトフレンドリーなAPIを作成するという大変な作業を行いましたNSOperation
。あなたがそうしない理由がない限り、彼らの仕事を利用してください。
警告:一方、本当にブロックを送信する必要があるだけで、NSOperationQueue
提供する追加機能が必要ない場合は、GCDの使用に問題はありません。それが仕事に適したツールであることを確認してください。
関連する質問への私の回答に沿って、私はBJに同意せず、最初にNSOperation / NSOperationQueueを介してGCDを確認することをお勧めします。
GCD以前は、同時実行性を管理するために、アプリケーション内で多くのNSOperations / NSOperationQueuesを使用していました。ただし、定期的にGCDを使い始めて以来、NSOperationsとNSOperationQueuesをほぼ完全にブロックとディスパッチキューに置き換えました。これは、実際に両方のテクノロジーをどのように使用したか、およびそれらに対して実行したプロファイリングに基づいています。
まず、NSOperationsとNSOperationQueuesを使用すると、かなりのオーバーヘッドが発生します。これらはCocoaオブジェクトであり、割り当てと割り当て解除を行う必要があります。60 FPSで3Dシーンをレンダリングする私が書いたiOSアプリケーションでは、NSOperationsを使用して、レンダリングされた各フレームをカプセル化していました。私がこれをプロファイリングしたとき、これらのNSOperationsの作成と破棄は、実行中のアプリケーションのCPUサイクルのかなりの部分を占めていて、物事を遅くしていました。これらを単純なブロックとGCDシリアルキューに置き換えたところ、そのオーバーヘッドがなくなり、レンダリングパフォーマンスが著しく向上しました。私がNSOperationsの使用によるオーバーヘッドに気づいたのはここだけではなく、MacとiOSの両方でこれを確認しました。
第2に、NSOperationsを使用するときに一致させるのが難しいブロックベースのディスパッチコードには優雅さがあります。数行のコードをブロックにラップし、それをシリアルキューまたは並行キューで実行するようにディスパッチするのは非常に便利です。これを行うには、カスタムNSOperationまたはNSInvocationOperationを作成するために、より多くのサポートコードが必要です。NSBlockOperationを使用できることは知っていますが、その場合はGCDに何かをディスパッチすることもできます。このコードをアプリケーションの関連処理とインラインでブロックでラップすると、これらのタスクをカプセル化する個別のメソッドやカスタムNSOperationsを使用するよりも、コードの編成が良くなります。
NSOperationsとNSOperationQueuesは、依然として非常に優れた用途があります。GCDには依存関係の実際の概念はありません。NSOperationQueuesはかなり複雑な依存関係グラフを設定できます。NSOperationQueuesを使用するのは、ほんの一握りの場合です。
全体として、私は通常、タスクを実行する最高レベルの抽象化を使用することを推奨していますが、これは、GCDの低レベルのAPIを主張する1つのケースです。私がこれについて話し合ったiOSとMacの開発者の中で、大多数がサポートしていないOSバージョン(iOS 4.0とSnow Leopardより前のもの)をターゲットにしていない限り、NSOperationsよりもGCDを使用することを選択します。
GCD
低レベルのCベースのAPIです。
NSOperation
そして、NSOperationQueue
Objective-Cのクラスです。
NSOperationQueue
目的のCラッパーGCD
です。NSOperationを使用している場合は、暗黙的にGrand Central Dispatchを使用しています。
NSOperationに対するGCDの利点:
i。実装
はGCD
実装が非常に軽量
NSOperationQueue
で複雑で重い
GCDに対するNSOperationの利点:
私。Control On Operation
では、一時停止、キャンセル、再開できます。NSOperation
ii。
2つのNSOperations
操作間の依存関係を設定できる依存関係は、その依存関係がすべてtrueに戻るまで開始されません。
iii。操作
の状態は、操作または操作キューの状態を監視できます。準備完了、実行中または終了
iv。最大
操作数:同時に実行できるキューに入れられた操作の最大数を指定できます
いつ、GCD
またはNSOperation
キュー(上記のすべて)をより詳細に制御する必要があるか、NSOperation
およびオーバーヘッドを減らしたい単純な場合(追加の作業をほとんど行わずに「バックグラウンドで」いくつかの作業を実行したいだけ)GCD
ref:
https
: //cocoacasts.com/choosing-between-nsoperation-and-grand-central-dispatch/ http://iosinfopot.blogspot.in/2015/08/nsthread-vs-gcd-vs-nsoperationqueue.html
http ://nshipster.com/nsoperation/
GCDよりもNSOperationを選ぶもう1つの理由は、NSOperationのキャンセルメカニズムです。たとえば、数十枚の写真を表示する500pxのようなアプリでは、NSOperationを使用して、テーブルビューまたはコレクションビューをスクロールするときに非表示の画像セルのリクエストをキャンセルできます。これにより、アプリのパフォーマンスが大幅に向上し、メモリフットプリントを削減できます。GCDはこれを簡単にサポートできません。
また、NSOperationを使用すると、KVOが可能になります。
ここで読書の価値があるEschatonからの記事です。
NSOperation
として、このために NSURLSessionTask.cancel
とNSURLSession.invalidateAndCancel
、この機能を提供します。一般的に、NSURLSession
の機能の一部を提供するNSOperationQueue
よう、NSURLSessionTask
の機能の一部を提供NSOperation
GCDは確かにNSOperationQueueよりもレベルが低く、その主な利点は、その実装が非常に軽量で、ロックのないアルゴリズムとパフォーマンスに重点を置いていることです。
NSOperationQueueはGCDで利用できない機能を提供しますが、それらは重要なコストで提供されます。NSOperationQueueの実装は複雑で重量があり、多くのロックを含み、GCDを内部で使用するのは最小限の方法のみです。
NSOperationQueueが提供する機能が必ず必要な場合は、それを使用してください。ただし、GCDで十分な場合は、直接使用して、パフォーマンスを向上させ、CPUと電力のコストを大幅に削減し、柔軟性を高めることをお勧めします。
NSQueueOperationsとGCDはどちらも、UIアプリケーションのメイントレッドを解放することで、バックグラウンドで個別のスレッドで重い計算タスクを実行できます。
さて、以前の投稿に基づいて、NSOperationsにはaddDependencyがあるため、次々に操作をキューに入れることができます。
しかし、作成できるGCDシリアルキューについても読んで、dispatch_queue_createを使用してキューで操作を実行します。これにより、一連の操作を順番に実行できます。
GCDに対するNSQueueOperationの利点:
依存関係を追加したり、依存関係を削除したりできるため、1つのトランザクションでは依存関係を使用して順次実行でき、他のトランザクションでは同時に実行できますが、GCDではこの方法で実行できません。
操作がキューにある場合、操作をキャンセルするのは簡単です。実行中の場合は停止できます。
同時操作の最大数を定義できます。
キューにある操作を一時停止できます
キューにある保留中の操作の数を確認できます。
GCDは非常に使いやすく、バックグラウンドで何かを実行したい場合は、コードを記述してバックグラウンドキューにディスパッチするだけです。NSOperationで同じことを行うには、追加の作業がたくさんあります。
NSOperationの利点は、(a)メッセージを送信できる実際のオブジェクトがあり、(b)NSOperationをキャンセルできることです。それは簡単なことではありません。NSOperationをサブクラス化する必要があります。キャンセルとタスクの正常終了の両方が正しく機能するように、コードを正しく記述する必要があります。したがって、単純なものにはGCDを使用し、より複雑なものにはNSOperationのサブクラスを作成します。(サブクラスNSInvocationOperationとNSBlockOperationがありますが、それらが行うすべてのことはGCDで簡単に行えるため、それらを使用する十分な理由はありません)。
まあ、NSOperationsは単にGrand Central Dispatchの上に構築されたAPIです。したがって、NSOperationsを使用しているときも、Grand Central Dispatchを実際に使用しています。NSOperationsがあなたが好きかもしれない素晴らしい機能を提供するだけです。一部の操作を他の操作に依存させたり、アイテムを合計した後にキューを並べ替えたりすることができます。実際、ImageGrabberはすでにNSOperationsと操作キューを使用しています!ASIHTTPRequestは内部でそれらを使用します。必要に応じて、さまざまな動作に使用する操作キューを設定できます。それであなたはどちらを使うべきですか?アプリにとって意味のある方。このアプリは非常にシンプルなので、Grand Central Dispatchを直接使用しただけで、NSOperationの豪華な機能は必要ありません。ただし、アプリでそれらが必要な場合は、自由に使用してください。