最近我遇到使用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何时会入队
答案 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
}