83

アプリで一連のダウンロードおよびデータベース書き込み操作を実行する必要があります。私は同じためにNSOperationandを使用してNSOperationQueueいます。

これは適用シナリオです:

  • 場所からすべての郵便番号を取得します。
  • 郵便番号ごとに、すべての家を取得します。
  • 家ごとに住民の詳細を取得する

前述のように、私はNSOperationfor each タスクを定義しました。最初のケース (タスク 1) では、すべての郵便番号を取得するためにサーバーに要求を送信しています。内のデリゲートNSOperationがデータを受け取ります。このデータはデータベースに書き込まれます。データベース操作は別のクラスで定義されています。クラスからNSOperation、データベース クラスで定義された書き込み関数を呼び出しています。

私の質問は、データベースの書き込み操作がメイン スレッドで行われるか、バックグラウンド スレッドで行われるかということです。内で呼び出して NSOperationいたので、別のスレッド (MainThread ではない) で実行されることを期待していましたNSOperationNSOperationとを扱っているときに、誰かがこのシナリオを説明してくれませんかNSOperationQueue

4

6 に答える 6

17

バックグラウンド スレッドでデータベースの書き込み操作を実行する場合は、そのスレッド用に を作成する必要がありNSManagedObjectContextます。

関連するサブクラスNSManagedObjectContextの start メソッドで背景を作成できます。NSOperation

コア データとの同時実行性については、Apple ドキュメントを確認してください。

メソッドを使用して作成し、そのメソッド内でリクエストを実行NSManagedObjectContextすることにより、独自のバックグラウンド スレッドでリクエストを実行する を作成することもできます。NSPrivateQueueConcurrencyTypeperformBlock:

于 2013-10-30T09:31:57.750 に答える
11

NSOperationQueueから

iOS 4 以降では、操作キューは Grand Central Dispatch を使用して操作を実行します。iOS 4 より前では、非同時操作用に個別のスレッドを作成し、現在のスレッドから同時操作を起動します。

そう、

[NSOperationQueue mainQueue] // added operations execute on main thread
[NSOperationQueue new] // post-iOS4, guaranteed to be not the main thread

あなたの場合、サブクラス化して独自の「データベーススレッド」を作成NSThreadし、performSelector:onThread:.

于 2013-11-01T13:32:27.270 に答える
10

NSOperation の実行スレッドはNSOperationQueue、操作を追加した場所によって異なります。あなたのコードでこのステートメントを見てください -

[[NSOperationQueue mainQueue] addOperation:yourOperation]; // or any other similar add method of NSOperationQueue class

これはすべて、作業命令が書かれている (期待される) 実際のモンスターであるmain方法で、それ以上のスレッド化を行っていないことを前提としています。NSOperation

ただし、同時操作の場合、シナリオは異なります。キューは、同時操作ごとにスレッドを生成する場合があります。これは保証されていませんが、システムのその時点でのシステム リソースと操作リソースの需要によって異なります。プロパティによって操作キューの同時実行性を制御できmaxConcurrentOperationCountます。

編集-

私はあなたの質問が興味深いと思ったので、自分で分析/ロギングを行いました。このようにメインスレッドで作成された NSOperationQueue があります-

self.queueSendMessageOperation = [[[NSOperationQueue alloc] init] autorelease];

NSLog(@"Operation queue creation. current thread = %@ \n main thread = %@", [NSThread currentThread], [NSThread mainThread]);
self.queueSendMessageOperation.maxConcurrentOperationCount = 1; // restrict concurrency

次に、NSOperation を作成し、addOperation を使用して追加しました。現在のスレッドを確認したときのこの操作のメインメソッドでは、

NSLog(@"Operation obj =  %@\n current thread = %@ \n main thread = %@", self, [NSThread currentThread], [NSThread mainThread]);

それはメインスレッドではありませんでした。そして、現在のスレッド オブジェクトがメイン スレッド オブジェクトではないことがわかりました。

そのため、メイン スレッドでのカスタム キューの作成 (操作間に同時実行性がない) は、操作がメイン スレッド自体でシリアルに実行されることを必ずしも意味しません。

于 2013-10-30T05:07:37.520 に答える
2

ドキュメントの要約は次のoperations are always executed on a separate threadとおりです(iOS 4以降は、GCDの基礎となる操作キューを意味します)。

実際に非メイン スレッドで実行されていることを確認するのは簡単です。

NSLog(@"main thread? %@", [NSThread isMainThread] ? @"YES" : @"NO");

スレッドで実行する場合、GCD/libdispatch を使用してメイン スレッドで何かを実行するのは簡単です。それは、コア データ、ユーザー インターフェイス、またはメイン スレッドで実行するために必要なその他のコードのいずれであってもです。

dispatch_async(dispatch_get_main_queue(), ^{
    // this is now running on the main thread
});
于 2013-11-02T19:52:00.000 に答える
-2

重要なスレッド化を行っている場合は、FMDatabaseQueueを使用する必要があります。

于 2013-10-30T02:10:45.527 に答える