2

私はこのコードを持っています

-(void) Method {

    // WAIT_CODE

    dispatch_async(myQueue,^{ CODE 1});
    dispatch_async(myQueue,^{ CODE 2});  
    dispatch_barrier_async(myQueue,^{
        // SOME CODE
        dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE }
    });
}

問題は、このメソッドを再度呼び出したときに SOME CODE がまだ実行されていない場合、続行する前に WAIT_CODE を待機する必要があることです (ただし、GUI はアクティブなままにしておく必要があります)... どうすればこれを行うことができますか?

4

3 に答える 3

1

セマフォを使用して同期することもできます。コードを構成する方法を次に示します。

-(void) Method 
{

  // Declared dispatch_semaphore_t _synch;
  // in init: _synch = dispatch_semaphore_create(1);
  // in dealloc: dispatch_release(_synch);
  //
  // Initialized with 1 so first call goes through.
  // Subsequent calls are serialized and must wait on a signal.
  //
  dispatch_time_t blockingSleepSecondsIfNotDone = 0.01;
  while (!dispatch_semaphore_wait(wait, DISPATCH_TIME_NOW))
      usleep(USEC_PER_SEC * blockingSleepSecondsIfNotDone);

  WAIT_CODE

  dispatch_async(myQueue,^{ CODE 1});
  dispatch_async(myQueue,^{ CODE 2});  
  dispatch_barrier_async(myQueue,^{
    SOME CODE
    dispatch_semaphore_signal(_synch);
    dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE }
  });
}
于 2012-09-22T05:33:11.373 に答える
1

オプション 1) メソッドへの他の呼び出しが実行されていない場合にのみ -method 内のコードが実行されるように、2 つ目のシリアル キューを追加することは理にかなっていますか?

たとえば、呼び出し元では次のようになります。

mySerialQueue = dispatch_queue_create("com.myapp.my-serial-queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(mySerialQueue, [self method]);

オプション 2) myQueue を並行ではなくシリアルにします (dispatch_barrier_async() は所有している並行キューでのみ機能するため、並行していると思います)。

myQueue = dispatch_queue_create("com.myapp.myqueue", DISPATCH_QUEUE_SERIAL);    
dispatch_async(myQueue,^{ CODE 1});
dispatch_async(myQueue,^{ CODE 2});  
dispatch_async(myQueue,^{
   SOME CODE
   dispatch_async(myQueue,^{
      WAIT_CODE
      dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE }
   });
});

オプション 3) コードを並べ替えて、SOME_CODE の後に WAIT_CODE を追加する

dispatch_async(myQueue,^{ CODE 1});
dispatch_async(myQueue,^{ CODE 2});  
dispatch_barrier_async(myQueue,^{
    SOME CODE  // this code must block
    WAIT_CODE  // this code must block
    dispatch_async(dispatch_get_main_queue(), ^{ GUI UPDATE }
});
于 2012-09-21T17:32:36.973 に答える
1

あなたは何をしようとしているのですか?

なぜあなたは待たなければならないのですか?

この関数を再度呼び出したときにキューがまだ実行中のSOME CODE場合、それらの「新しい」ブロックはキューに入れられ、SOME CODEブロックが実行されるまで実行されません。myQueue私は同時キューであると仮定します。バリア呼び出しは、以前にキューに入れられたすべてのブロックが実行されるのを待ってから実行されます。さらに、それがキューで実行される唯一のブロックになり、完了するまで、キューはブロックの同時実行を再開します。

于 2012-09-21T21:24:22.917 に答える