1. ホーム
  2. ios

[解決済み] NSOperationとNSOperationQueueのワーキングスレッドとメインスレッドの比較

2023-06-25 05:45:59

質問

私のアプリで、一連のダウンロードとデータベースへの書き込み操作を実行する必要があります。私は NSOperationNSOperationQueue を同じにします。

これはアプリケーションのシナリオです。

  • ある場所からすべての郵便番号を取得します。
  • 各郵便番号について、すべての家をフェッチします。
  • 各家屋について、住民の詳細をフェッチする。

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

私の質問は、データベースの書き込み操作は、メインスレッドとバックグラウンドスレッドのどちらで発生するのでしょうか?私はそれを NSOperation の中で呼び出したので、別のスレッド(MainThreadではない)で実行されることを期待していました。 NSOperation . 誰かこのシナリオを説明してください。 NSOperationNSOperationQueue .

どのように解決するのですか?

<ブロッククオート

私の質問は、データベースの書き込み操作は、メインスレッドとバックグラウンドスレッドのどちらで発生するのでしょうか? スレッドで発生するのか、バックグラウンドスレッドで発生するのかということです。

もしあなたが NSOperationQueue のようにゼロから作成します。

NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];

バックグラウンドのスレッドになります。

オペレーションキューは通常、そのオペレーションを実行するために使用されるスレッドを提供します。 を提供します。OS X v10.6 以降では、オペレーションキューは、オペレーションを開始するために libdispatch ライブラリ (Grand Central Dispatch とも呼ばれます) を使用して、オペレーションの実行を開始します。 を使用します。 その結果、オペレーションは常に 別のスレッドで実行されます。 その結果、操作は常に別々のスレッドで実行され、それが 同時処理、非同時処理の指定に関わらず

を使用していない限り mainQueue :

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];

このようなコードも見受けられます。

NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
[myQueue addOperationWithBlock:^{

   // Background work

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // Main thread work (UI usually)
    }];
}];

そしてGCD版。

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
             {
              // Background work            
             dispatch_async(dispatch_get_main_queue(), ^(void)
              {
                   // Main thread work (UI usually)                          
              });
});

NSOperationQueue は、やりたいことをより細かく制御することができます。2つの操作(ダウンロードとデータベースへの保存)の間に依存関係を作成することができます。あるブロックと他のブロックの間でデータを受け渡すには、たとえば NSData がサーバから送られてくると仮定します。

__block NSData *dataFromServer = nil;
NSBlockOperation *downloadOperation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakDownloadOperation = downloadOperation;

[weakDownloadOperation addExecutionBlock:^{
 // Download your stuff  
 // Finally put it on the right place: 
 dataFromServer = ....
 }];

NSBlockOperation *saveToDataBaseOperation = [[NSBlockOperation alloc] init];
__weak NSBlockOperation *weakSaveToDataBaseOperation = saveToDataBaseOperation;

 [weakSaveToDataBaseOperation addExecutionBlock:^{
 // Work with your NSData instance
 // Save your stuff
 }];

[saveToDataBaseOperation addDependency:downloadOperation];

[myQueue addOperation:saveToDataBaseOperation];
[myQueue addOperation:downloadOperation];

編集します。 なぜ __weak 操作の参考文献はこちらです。 はこちら . しかし、一言で言えば、サイクルを保持しないようにすることです。