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

Ios 状态更改后,GCD将块添加到串行队列中,ios,objective-c,objective-c-blocks,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); });

最近我在使用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()方法将块添加到队列中时,状态都已完成。换句话说,当调用测试时,检查状态,如果发现状态正在处理,请等待状态更改为finished,然后执行dispatch_async()

我怎样才能实现这个,谢谢你的帮助

编辑:


doSomethingWithFinishBlock是一个异步函数,我不知道onFinish块何时进入队列

您应该在创建调度队列时使用
DISPATCH\u QUEUE\u SERIAL
(“com.somnus.xxx”,NULL)

那你就不用这么做了

当块排队并一个接一个地执行时

块的存在使您不必积极等待。你不必有状态变量

整个事情就是:

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", DISPATCH_QUEUE_SERIAL);
    });

    return sl_queue;
}

- (void)test
{
    dispatch_async(queue(), ^{
        [someObj doSomethingWithFinishBlock:nil];
    });
}

这通常是通过一个
dispatch\u信号量来完成的。大致如下:

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

doSomethingWithFinishBlock
是异步函数吗?@Cy-4AH是的,doSomethingWithFinishBlock是一个异步函数“你应该在你的调度队列中使用调度队列序列”(“com.somnus.xxx”,NULL);”
调度队列序列定义为
NULL
,我想确保onFinish块在下一个[someObj doSomethingWithFinishBlock:nil]块之前排队。@newacct代码可读性很重要,没有人知道NULL的意思docs@Alistra:实际上,在以前版本的SDK中,当只能创建串行队列时,该参数未使用,文档特别告诉您传递
NULL
。后来,他们添加了创建并发队列的功能,并添加了
DISPATCH\u QUEUE\u SERIAL
DISPATCH\u QUEUE\u concurrent
。他们在那里有
NULL
这一事实并不意味着它写得很差。@Alistra:无论如何,问题是你关于“那么你就不必做…”的陈述是不正确的或不相关的,因为
DISPATCH\u QUEUE\u SERIAL
NULL
之间没有区别。
@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];
   });
}