繁体   English   中英

iOS RunLoop 和 DispatchQueue.main.async

[英]iOS RunLoop and DispatchQueue.main.async

为什么print("2")部分永远不会在以下代码中被调用? 我认为内部main.async会将块推送到主循环的队列中,然后RunLoop.run会执行它,但显然不是这样。 (它打印1runrunrun等)

此外,如果我删除外部main.async ,并直接运行该块中的代码(仍在主队列中,在新的单视图应用程序的viewDidLoad中),那么内部main.async块确实会被执行(打印1run2 )。 为什么这种变化会产生如此大的影响?

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调用返回,这在x1时不会发生。 该内部 GCD async任务(将x更新为2 )将永远没有机会运行,因为该串行 GCD 队列现在在该while循环中被阻塞。 在主运行循环上run的尝试不会规避 GCD 串行队列的规则/行为。 它只会耗尽已添加到其中的事件的运行循环。

在您的第二个示例中,您没有阻塞 GCD main队列,因此当您点击run时,将x更新为2的调度块确实有机会运行,让它继续。

最重要的是,不要将 GCD 主队列和主运行循环混为一谈。 是的,它们都使用主线程,但不能使用运行循环来规避串行 GCD 队列的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM