【发布时间】:2020-10-17 17:13:09
【问题描述】:
为什么print("2") 部分从未在以下代码中被调用?
我认为内部 main.async 会将块推送到主循环的队列中,
然后RunLoop.run 会执行它,但显然不是这样。
(它会打印1、run、run、run 等)
另外,如果我删除外部main.async,然后直接运行该块中的代码
(仍在主队列中,在一个新的单视图应用程序的viewDidLoad 中),
然后内部的main.async 块确实被执行(打印1、run、2)。
为什么这种变化会产生如此大的影响?
var x = -1
DispatchQueue.main.async { // comment out this line for question #2
print("1")
x = 1
DispatchQueue.main.async {
print("2")
x = 2
}
while x == 1 {
print("run")
RunLoop.main.run(mode: .default, before: Date() + 1)
}
} // comment out this line for question #2
【问题讨论】:
-
FWIW,在运行循环上旋转的笨拙技术有点不合时宜。我们现在不经常看到它。当有人试图使一个固有的异步进程同步运行时,通常使用它,并使用这种运行循环技术至少让运行循环来处理事件。但正如您所发现的,它并不理想,并且会引入这些问题。此外,通常还有更好、更有效的解决方案(例如,采用异步模式而不是与之抗衡)。
-
@Rob 我知道,我知道。我试图做类似事情的用例基本上是一个调试工具,它用联网的 RPC 调用代替了通常的同步调用,理想情况下,如果我可以使用它而不必修改调用者,那就太好了。
-
好的。但我不得不说,至少为了未来的读者。太多不熟悉异步模式的新开发人员倾向于使用这些变通方法。无意冒犯。
标签: ios nsrunloop dispatch-queue