状态更改后,GCD将块添加到串行队列中

时间:2015-09-08 15:40:16

标签: ios objective-c objective-c-blocks

最近我遇到使用GCD的问题。以下是一些代码段:

static dispatch_queue_t queue() {
    static dispatch_queue_t sl_queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sl_queue = dispatch_queue_create("com.somnus.xxx", NULL);
    });

    return sl_queue;
}

- (void)test
{
        while (self.state != finished)
        {
            //wait for finish
        }

        dispatch_async(queue(), ^{

                self.state = processing;


            void (^onFinish)(void) = 0;
            onFinish = ^(void){
                self.state = finished; 
            };

            [someObj doSomethingWithFinishBlock:onFinish];

        });
}

我想确保每当test()方法将块添加到队列中时,状态就完成了。换句话说,当调用test时,检查状态,如果发现状态正在处理,等待它更改为finished,然后执行dispatch_async()。

我可以实现这一点,感谢您的帮助!

编辑:

doSomethingWithFinishBlock是一个异步函数,我不知道onFinish Block何时会入队

2 个答案:

答案 0 :(得分:2)

这通常使用dispatch_semaphore完成。这些方面的东西:

@property (nonatomic, readwrite, strong) dispatch_semaphore_t sem;

// ... At some point you must initialize it to 1
// this essentially creates a pool of 1 token to share.
self.sem = dispatch_semaphore_create(1);

- (void)test
{
    // Checkout a token from the pool (there's only one)
    // block until I can get get. You could also timeout, which can be useful.
    dispatch_semphore_wait(self.sem, DISPATCH_TIME_FOREVER);

    // Do a weak-self dance here if you need one. You may not in your example.
    dispatch_async(queue(), ^{
        dispatch_block_t onFinish = ^{
            // Return the token to the pool
            dispatch_semaphore_signal(self.sem)
        };

        [someObj doSomethingWithFinishBlock:onFinish];
   });
}

答案 1 :(得分:0)

您应该在dispatch_queue_create中使用idevicediagnostics ioreg IOPower(“com.somnus.xxx”,NULL);

然后你就不必做了

DISPATCH_QUEUE_SERIAL

当块被排队并一个接一个地执行。

存在阻止,因此您无需主动等待。那么你不必拥有状态变量。

整件事情就是:

    while (self.state != finished)
    {
        //wait for finish
    }