7

アプリの設計上の問題に直面しています。


基本的に、アプリでやろうとしていることは次のとおりです。

単一のタスクは次のようになります。

  1. 基になる CoreData データベースからカスタム オブジェクトを読み取る
  2. URLからjsonをダウンロードする
  3. json を解析してカスタム オブジェクトを更新するか、新しいオブジェクトを作成します (解析には 1 ~ 3 秒かかる場合があります。ビッグ データ)。
  4. カスタム オブジェクトを分析します (一部の計算が含まれます。1 ~ 5 秒かかる場合があります)。
  5. カスタム オブジェクトを CoreData データベースに保存します。

多数のタスクが同時に実行される場合があります。

1 つのタスク内のステップは明らかにordered(つまり、ステップ 2 で json をダウンロードしないと、ステップ 3 を続行できません) ですが、discrete. たとえば、タスク 2 のステップ 4 は、タスク 1 のステップ 3 の前に実行できます (タスク 2 のダウンロードがタスク 1 よりも速い場合)。

タスクには優先順位があります。ユーザーは優先度の高いタスクを開始できるため、タスクのすべてのステップが他のすべてのステップより先に実行されます。


UI はできるだけレスポンシブであることが望ましいです。

したがって、優先度が最も低い NSThread を作成するつもりでした。

そのスレッドにカスタム優先イベント キューを配置しました。タスクのすべてのステップがイベント (作業単位) になります。したがって、たとえば、json をダウンロードするステップ 1 がイベントになります。ダウンロード後、イベントはステップ 3 の別のイベントを生成し、キューに入れられます。すべてのイベントには独自の優先順位が設定されています。


今、この記事を目にしました: Concurrency and Application Design。Apple は、 weとorMove Away from Threadsを使用することを提案しています。GCDNSOperation

私はそれがNSOperation私のドラフトデザインと非常に一致していることに気づきました. しかし、次の質問があります。

  • iPhone/iPad の CPU コアを考慮して、NSOperationQueue を 1 つだけ使用するか、複数作成する必要がありますか?
  • NSOperationQueue または NSOperation は、最も低いスレッド優先度で実行されますか? 実行は UI の応答に影響を与えますか (ステップには計算が含まれるので気にします)。
  • 別のものから NSOeartion を生成してキューに入れることはできますか? NSOperation にキュー プロパティが表示されません。どうすればキューを確認できますか?
  • NSOperationQueue を CoreData と連携させるにはどうすればよいですか? CoreData にアクセスするたびに、新しいコンテキストを作成する必要がありますか? それは高価になりますか?
  • タスクの各ステップが NSOperation になります。この設計は正しいですか?

ありがとう

4

5 に答える 5

4

iPhone / iPadのCPUコアを考慮すると、1つのNSOperationQueueを使用する必要がありますか、それとも複数のNSOperationQueueを作成する必要がありますか?

2つ(CPU、ネットワーク+ I / O)または3つ(CPU、ネットワーク、I / O)のシリアルキューは、ほとんどの場合にうまく機能し、アプリの応答性を維持し、プログラムのストリーミングがバインドされたものによって機能するようにします。もちろん、あなたはあなたの特定の仕事の分配のために別の組み合わせ/公式の仕事を見つけるかもしれません。

NSOperationQueueまたはNSOperationは、最も低いスレッド優先度で実行されますか?実行はUI応答に影響しますか(ステップには計算が含まれるため、気になります)?

デフォルトではありません。-[NSOperation setThreadPriority:]優先度を下げたいかどうかを確認してください。

別のNSOpeartionからNSOpeartionを生成して、キューに入れることはできますか?NSOperationにキュープロパティが表示されません。キューを知るにはどうすればよいですか?

もちろん。概説したシリアルアプローチを使用する場合、正しいキューを見つけるのは簡単です。または、ivarを使用することもできます。

NSOperationQueueをCoreDataと連携させるにはどうすればよいですか?CoreDataにアクセスするたびに、新しいコンテキストを作成する必要がありますか?それは高くつくでしょうか?

(コメント無し)

タスクの各ステップはNSOperationになりますが、この設計は正しいですか?

はい-キューをバインドされているリソースに分割することをお勧めします。

于 2012-09-05T14:51:14.393 に答える
0

NSOperationの代わりにNSThreadを使用しているという理由だけで、マルチスレッドの場合の計算の影響は変わりません。ただし、現在のiOSデバイスはデュアルコアプロセッサを使用している必要があることに注意してください。

あなたが持っている質問のいくつかはあまり具体的ではありません。複数のNSOperationQueueを使用する場合と使用しない場合があります。それはすべて、あなたがそれにどのようにアプローチしたいかに依存します。異なるNSOperationサブクラスまたは異なるNSBlockOperationsがある場合は、優先順位を使用して実行の順序を管理できます。または、操作のタイプごとに異なるキューを使用したい場合があります(特にシリアルキューを操作する場合)。私は個人的に、同じタイプの操作を処理する場合は1つの操作キューを使用し、操作が関連/依存しない場合は別の操作キューを使用することを好みます。これにより、何かが起こったこと(ネットワークのドロップ、アプリのバックグラウンドへの移行)に基づいて、キュー内の操作をキャンセルおよび停止する柔軟性が得られます。

現在の操作の実行中に発生した何かに基づいて操作を追加する正当な理由を見つけたことがありません。これを行う必要がある場合は、NSOperationQueueのクラスメソッドcurrentQueueを使用できます。これにより、現在の操作が動作している操作キューが提供されます。

NSOperationを使用してコアデータ作業を行っている場合は、特定の操作ごとにコンテキストを作成することをお勧めします。メインメソッド内のコンテキストを初期化するようにしてください。これは、NSOperationバックグラウンド実行の正しいスレッドにいる場所だからです。

タスクごとに1つのNSOperationオブジェクトを用意する必要はありません。データをダウンロードして、NSOperation内で解析できます。NSOperationのcompletionblockプロパティを使用して、データのダウンロードを抽象的に実行し、ダウンロードしたコンテンツのデータ操作を実行することもできます。これにより、同じオブジェクトを使用してデータを取得できますが、データ操作は異なります。

NSOperation、NSBlockOperation、NSOperationQueueのドキュメントを読むことをお勧めします。現在の設計をチェックして、これらのクラスを現在のプロジェクトにどのように適合させることができるかを確認してください。NSThreadファミリーではなく、NSOperationファミリーのルートを使用することを強くお勧めします。

幸運を。

于 2012-09-05T14:53:55.370 に答える
0

@justinの答えに追加するだけです

NSOperationQueueをCoreDataと連携させるにはどうすればよいですか?CoreDataにアクセスするたびに、新しいコンテキストを作成する必要がありますか?それは高くつくでしょうか?

NSOperationCore Dataで使用する場合は、十分に注意する必要があります。
ここで常に覚えておく必要があるのは、別のスレッドでCoreData操作を実行する場合は、NSManagedObjectContextそのスレッド用に新しいスレッドを作成し、メインの管理対象オブジェクトコンテキスト永続ストアコーディネーターを共有する必要があるということです(「メイン」MOCはアプリデリゲート)。

また、そのスレッドの新しい管理対象オブジェクトコンテキストがそのスレッドから作成されることが非常に重要です。したがって、Core Dataをで使用する場合は、NSOperationのメソッドで.ではなく新しいMOCを初期化するようにしてください。NSOperationmaininit

これがコアデータとスレッド化についての本当に良い記事です

于 2012-09-05T15:51:05.730 に答える
0
  • 見た目では、 NSOperationQueue はあなたが求めているものです。同時に実行する同時操作の数を設定できます。複数の NSOperation を使用する場合、それらはすべて同時に実行されます...自分でキューを処理しない限り、NSOperationQueue を使用するのと同じになります

  • スレッドの優先度・・・何を言っているのかよくわかりませんが、iOSではUIの描画もイベントもユーザーとのやり取りもすべてメインスレッドで実行されます。バックグラウンド スレッドで実行している場合、実行中の操作がどれほど複雑で CPU 負荷が高くても、インターフェースは応答性を維持します。

  • 操作の生成と処理はメイン スレッドで行う必要があります。時間がかからないため、メイン スレッドがロックされないようにバックグラウンド スレッドで実行するだけです。

  • CoreData、私は特にそれを使ったことはありませんが、これまでに私が使ったすべての Core~ はバックグラウンド スレッドで完全に動作するので、問題にはなりません。

  • 設計に関する限り、それは単なる観点です... 私としては、タスクごとに 1 つの NSOperation を使用して、すべてのステップを処理するようにします。フィードバックを提供したり、別のダウンロードや何かを続行したい場合は、ステップが終了するたびにコールバックを書くかもしれません

于 2012-09-05T14:48:19.820 に答える
-1

GCDを使用する-NS*よりもはるかに優れたフレームワーク

すべてのCoreDataアクセスを1つのキューに保持し、ルーチンの最後にdispatch_asyncを保持して、CoreDataデータベースに保存し直します。

開発者アカウントをお持ちの場合は、次のWWDCビデオをチェックしてください:https ://developer.apple.com/videos/wwdc/2012/?id = 712

于 2012-09-05T15:34:48.163 に答える