重置dispatch_once_t?

时间:2014-02-06 20:16:51

标签: objective-c cocoa locking

根据the answer of this post,您不应重置dispatch_once_t isn't a good thing to do in any situation other than testing

假设我有一段代码,我想确保一次不能被多个线程调用(比如加载数据)。这不是有效的代码:

@interface SomeClass()
{
    dispatch_once_t onceToken;
}
@end

- (void) updateMethod
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        dispatch_once(&onceToken, ^{
            // Do some data loading in the background.
            ...

            dispatch_async(dispatch_get_main_queue(), ^{
                // Update the UI
                ...

                // Reset the once token. Allow the method to be called again.
                onceToken = 0;
            });
        });
    });
}

此代码有任何问题吗?或者应该以另一种方式完成?

1 个答案:

答案 0 :(得分:3)

您不应尝试将dispatch_once用于此目的。对于此类任务,您应该使用串行队列或某种锁或信号量,具体取决于您的需要。

对于第一个选择,您可以并行加载后台,但将UI更新排入主队列,这是一个串行队列,主队列上应该进行UI更新。

如果您需要将后台加载设置为串行,并将其排入串行队列,则可以使用dispatch_queue_create()创建一个。

对于第二种选择,GCD提供信号量 - dispatch_semaphore_create()dispatch_semaphore_signal()dispatch_semaphore_wait()

概述你:

  1. 创建一个计数为1的信号量。
  2. 当您想要运行等待信号量时,如果信号量的值为0,则阻止您的线程,对于> 0计数递减,线程继续
  3. 完成工作后,您会发信号通知信号量 - 增加信号量
  4. HTH