[英]iOS RunLoop and DispatchQueue.main.async
为什么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
在您的第一个示例中,第一个async
阻塞main
串行队列,直到它从外部async
调用返回,这在x
为1
时不会发生。 该内部 GCD async
任务(将x
更新为2
)将永远没有机会运行,因为该串行 GCD 队列现在在该while
循环中被阻塞。 在主运行循环上run
的尝试不会规避 GCD 串行队列的规则/行为。 它只会耗尽已添加到其中的事件的运行循环。
在您的第二个示例中,您没有阻塞 GCD main
队列,因此当您点击run
时,将x
更新为2
的调度块确实有机会运行,让它继续。
最重要的是,不要将 GCD 主队列和主运行循环混为一谈。 是的,它们都使用主线程,但不能使用运行循环来规避串行 GCD 队列的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.