我试图理解这种常见模式:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// Background stuff on background thread
dispatch_async(dispatch_get_main_queue()) {
// Update UI on main thread
}
}
Apple文献states:
完成回调可以通过对dispatch_async()函数的嵌套调用来完成。
好的,但我认为dispatch_async
的FIFO方面是它保证在提交的顺序中开始的任务。我认为它并不能保证它们能以任何顺序完成吗?
我的问题是,为什么嵌套调用是否等待它嵌套的闭包/阻塞的完成?
如果我要写
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
doThing1()
doThing2()
doThing3()
}
是否可以保证doThing2()
在执行前等待doThing1()
的执行?如果是这样,这是否意味着它相当于两个后续的dispatch_ sync 调用,如下所示:
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
doThing1()
}
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
doThing2()
}
答案 0 :(得分:0)
好的,但我认为dispatch_async的FIFO方面是它保证任务以提交的顺序开始。我认为它并不能保证它们能以任何顺序完成吗?
您是对的,但这也取决于这是一个串行还是并发队列。对于串行队列,输入顺序是完成顺序:在队列中的前面的项目完成之前不会发生任何新的事情。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
doThing1()
doThing2()
doThing3()
}
在该代码中,它与哪种队列无关。你的代码都在一个区块内。该块中的事物顺序不会被神奇地洗牌!这将使整个编程概念无意义。
然而,在你引用的句子中,没有一个能达到Apple的意思。嵌套的完成块对于工作方式至关重要,因为它们意味着您可以从主线程获取后台线程,执行某些操作,然后,当完成后,返回主线程并执行更多操作。这是按顺序发生的。这可以保证您可以遵守不必在后台线程上触摸界面的重要规则。此外,在这种安排中,来自周围区块的本地人是可见的,因此数据从一个区块安全地传递到另一个区块,如本书中的例子所示:
- (void) drawThatPuppy {
CGPoint center =
CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
dispatch_async(self->_draw_queue, ^{
CGContextRef bitmap = [self makeBitmapContext: self.bounds.size];
[self drawAtCenter: center zoom: 1 context:bitmap];
dispatch_async(dispatch_get_main_queue(), ^{
if (self->_bitmapContext)
CGContextRelease(self->_bitmapContext);
self->_bitmapContext = bitmap;
[self setNeedsDisplay];
});
});
}