ios - iOS RunLoop 和 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
串行队列,直到它从该外部调用返回,这在isasync
时不会发生。该内部 GCD任务(更新到)将永远没有机会运行,因为该串行 GCD 队列现在在该循环中被阻塞。在主运行循环上的尝试不会规避 GCD 串行队列的规则/行为。它只会耗尽已添加到其中的事件的运行循环。x
1
async
x
2
while
run
在您的第二个示例中,您没有阻止 GCDmain
队列,因此当您点击 时,更新到run
的已调度块确实有机会运行,让它继续。x
2
最重要的是,不要将 GCD 主队列和主运行循环混为一谈。是的,它们都使用主线程,但不能使用运行循环来规避串行 GCD 队列的行为。
推荐阅读
- java - 使用 Eclipse IDE 的 Java 代码问题(初级程序员)
- rss - dpdk19.11 ixgbe rx 队列增加到 22 没有生效,
- oracle - 一旦一个分支在 oracle apex 20.1 中无法执行后执行了其他分支
- multithreading - 使用 Julia 绘制具有多线程、竞争条件问题的 mandelbrot
- android - 如何在android recyclerview中从服务器访问json文件的子文件和子文件
- ruby-on-rails - 在 Rails 中干燥方法调用
- php - laravel,在 forloop 中使用 updateOrCreate
- grafana - 如何在influxdb / grafana中添加多个查询的结果
- bash - vi is hashed to ( 之间有什么区别
) 和 vim 是 ? - google-apps-script - 根据带有宏/脚本的工作表的位置动态更新 rspreadsheet.getRange() 列