我有这个代码
-(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必须保持活动状态)...我该怎么做?
答案 0 :(得分: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_CODEdispatch_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 }
});
答案 1 :(得分:1)
你想做什么?
你为什么要等?
如果再次调用此函数时队列仍在执行SOME CODE
,那么这些“新”块将被排队,并且在SOME CODE
块运行之后才会执行。我假设myQueue
是并发队列。屏障调用将等待所有先前排队的块在运行之前执行。此外,它将是队列上运行的唯一块,直到完成,然后队列将同时恢复执行块。
答案 2 :(得分: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 }
});
}