Ios 状态更改后,GCD将块添加到串行队列中
最近我在使用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); });
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];
});
}