问题很简单,但我找不到合理的答案。 在像这样的代码中
dispatch_queue_t background_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL);
dispatch_async(background_queue, ^{
// do some stuff that takes a long time here...
// follow up with some stuff on the main queue
dispatch_async(dispatch_get_main_queue(), ^{
// Typically updating the UI on the main thread.
});
});
“background_queue”是并发队列,因此其中的任务将按顺序启动,但可能无法以相同的顺序完成。因此,我们可以在下载图像之前调用更新UI块。 更多说明将有所帮助,谢谢。
答案 0 :(得分:1)
在这个例子中,两个GCD块将按顺序完成,因为外部块只会在长进程完成后调用内部块(更正确一点,它应该是dispatch_sync
上的内部块)
这将保证顺序,因为后台线程将在即将完成之前调用主线程的gcd块,并且仅在长任务完成之后调用
dispatch_async(background_queue, ^{
// do some stuff that takes a long time here...
// follow up with some stuff on the main queue
dispatch_sync(dispatch_get_main_queue(), ^{ //should be sync not async, but in practice should have little impact if nothing happens after this block
// Typically updating the UI on the main thread.
});
});
这不会,因为两个gcd块将同时执行,并且不会等待彼此完成
dispatch_async(background_queue, ^{
// do some stuff that takes a long time here...
});
// follow up with some stuff on the main queue
dispatch_async(dispatch_get_main_queue(), ^{
// Typically updating the UI on the main thread.
});
答案 1 :(得分:0)
嗯,我想在这个简短的回答中我无法完全解释GCD机制,但我会给出一个简短的总结:
有串行和并发队列:
然后,有两种方法可以将工作项排入队列: async 和 sync 。这涉及呼叫将如何返回:
例如,如果您将工作项同步排入当前队列,则会导致死锁。
但GCD还有更多的方法,例如你可以将工作项目分组并等到所有项目都完成,或者你可以开始"高优先级"工作项目将是首选。
答案 2 :(得分:0)
在长任务完成后,您回到主队列上。 我将向您展示一个我正在开发的应用程序中的示例:
- (void)coinRequest {
dispatch_queue_t coinsQueue = dispatch_queue_create("getUserCoins", NULL);
dispatch_async(coinsQueue, ^{
EMGetUserCoinsRequest* request = [EMGetUserCoinsRequest new];
__weak typeof(self) _self = self;
[self putCurrentRequest:request];
request.suppressLoadingView = YES;
[BackEnd() performRequest:request force:YES onSuccess:^(EMGetUserCoinsResponse *response) {
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
if (response.coins.coins != NULL) {
_self.coinsLabel.text = [NSString stringWithFormat:@"%@", response.coins.coins];
} else {
_self.coinsLabel.text = [NSString stringWithFormat:@"0"];
}
});
} onApplicativeError:NULL onEnvironmentError:NULL];
});
}
正如您所见,我有一个请求用户硬币的请求。由于UI必须保持响应,我使用bg队列。下载信息后,在" onSuccess"块我回到主线程以更新UI。
答案 3 :(得分:0)
在操场上玩!
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
import Foundation
var s0 = ""
var s1 = ""
let queue = DispatchQueue(label: "cq", attributes: .concurrent)
let worker0 = { ()->() in
for i in 0..<5000 {
if (i % 1000) == 0 {
print(i / 1000, terminator: "", to: &s0)
}
}
}
let worker1 = { ()->() in
for i in 0..<5000 {
if (i % 1000) == 0 {
print(i / 1000, terminator: "", to: &s1)
}
}
}
queue.async(execute: {
worker0()
worker0()
worker0()
worker0()
print(s0, " all workers0 were executed serialy")
})
let dg = DispatchGroup()
queue.async(group: dg, execute: worker1)
queue.async(group: dg, execute: worker1)
queue.async(group: dg, execute: worker1)
queue.async(group: dg, execute: worker1)
dg.wait()
print(s1, " workers1 were executed concurrently")
它会打印类似
的内容00101212323434041234 workers1 were executed concurently
01234012340123401234 all workers0 were executed serialy
分派到任何队列的执行块中写入的所有代码都按顺序执行&#34;