我有一些看起来像这样的代码:
DispatchQueue.global(qos: .userInitiated).async {
self.fetchProjects()
DispatchQueue.main.async {
self.constructMenu()
}
}
我的问题是全局块中的块是否按顺序执行?当我添加打印语句时,它们总是以相同的顺序执行,但是我不确定在查看文档时是否很幸运,它说:
提交到返回队列中的任务是相对于彼此并发安排的。
我想知道是否有人可以对此进行解释?
编辑:
抱歉,我认为我没有把问题弄清楚。我希望方法constructMenu
仅在fetchProjects
完成后才被调用。据我所知(通过记录打印语句)是这种情况。
但是我真的不确定为什么,如果上述Apple文档所说的(每个任务是同时安排的)是真的。
是异步块中的代码总是串行执行,还是使用DispatchQueue.main
似乎是串行执行代码,还是只是运气好,在某个时候constructMenu
实际返回之前 fetchProjects
?
答案 0 :(得分:1)
是的,代码块作为块提交,并且这些块按顺序运行。因此,对于您的示例:
DispatchQueue.global(qos: .userInitiated).async {
self.fetchProjects()
DispatchQueue.main.async {
self.constructMenu()
}
}
fetchProjects()
必须先完成constructMenu
的入队。这里没有魔术。 {...}
之间的块将作为一个块提交。在将来的某个时候它将执行。但是不会以任何精细的方式考虑块的各个部分。它们将从顶部fetchProjects
开始,然后将执行下一行代码DispatchQueue.main.async
,该代码接受另一个块作为参数。编译器对这些块一无所知。它只是将它们传递给函数,然后这些函数将它们放在队列中。
答案 1 :(得分:1)
我希望方法
constructMenu
仅在fetchProjects
完成后才被调用。据我所知(通过记录打印语句)是这种情况。
是的,就是这种情况。
但是我真的不确定为什么上面苹果文件中所说的(每个任务是同时安排的)是真的。
Apple的文档说,两个相互独立的调度程序可以同时运行。
考虑:
DispatchQueue.global(qos: .userInitiated).async {
foo()
}
DispatchQueue.global(qos: .userInitiated).async {
bar()
}
在这种情况下,foo
和bar
可能会同时运行。这就是Apple所说的“同时计划提交给返回队列的任务”。
但是请考虑:
DispatchQueue.global(qos: .userInitiated).async {
foo()
bar()
}
在这种情况下,bar
不会运行,直到我们从foo
返回。
是异步块中的代码总是串行执行,还是使用
DispatchQueue.main
似乎是串行执行代码,还是只是运气好,在某个时候constructMenu
真的在fetchProjects
之前返回?
不涉及运气。除非您从DispatchQueue.main.async
返回,否则它永远不会到达fetchProjects
行。
不过,有一个相当重要的警告。假设fetchProjects
在提取完成之前不会返回。这意味着fetchProjects
最好不要自行启动任何异步进程(即没有网络请求)。如果是这样,您可能想为其提供一个完成处理程序,并将调用移至该完成处理程序中的constructMenu
。
答案 2 :(得分:0)
DispatchQueue.global
是并发队列,这意味着所有提交的任务同时异步运行(如果需要的话,可以依次创建一个自定义队列
let serial = DispatchQueue(label: "com.queueName")
serial.sync {
///
}