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 }
    });
}

问题是,当我再次调用此方法并且尚未执行某些代码时,我需要等待 WAIT_CODE 才能继续(但 GUI 必须保持活动状态)......我该怎么做?

4

3 回答 3

1

选项 1) 添加第二个串行队列是否有意义,以便 -method 中的代码仅在没有其他对该方法的调用正在执行时运行?

例如,在调用者中,您将拥有:

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

您还可以使用信号量进行同步。这是您的代码的结构方式。

-(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

你想做什么?

为什么你必须等待?

如果再次调用此函数时队列仍在执行,则那些“新”块将入队,直到块运行SOME CODE后才会执行。SOME CODE我假设myQueue是一个并发队列。屏障调用将等待所有先前排队的块在运行之前执行。此外,它将是队列上唯一运行的块,直到它完成,然后队列将恢复并发执行块。

于 2012-09-21T21:24:22.917 回答