繁体   English   中英

viewWillAppear 中的 DispatchQueue.main.async 块是否总是在 viewDidLayoutSubviews 之后调用?

[英]Is `DispatchQueue.main.async` block in viewWillAppear always called after `viewDidLayoutSubviews`?

我想在推送 VC 后立即更改集合视图的 contentOffset.x。
所以我在 viewWillAppear 中调用了collectionView.setContentOffset(~)
但由于自动布局循环,它不起作用。

但是,如果我在DispatchQueue.main.async块中调用collectionView.setContentOffset ,就可以了!

代码如下:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    DispatchQueue.main.async {
        collectionView.setContentOffset(
            CGPoint(x: currentFolderIndex * collectionView.bounds.width), y: 0), 
            animated: false
        )
    }
}

当我打印布局方法的顺序时,我弄清楚了为什么它会起作用。

在此处输入图像描述

DispatchQueue.main.async块在viewDidLayoutSubviews之后调用。

它总是这样吗?
为什么它会这样工作?
我很好奇!!

使用async基本上就是说“有时间就做”。 所以它会在未来不确定的时间(一般不会太久)完成,并且可能在完成当前正在做的事情之后。 而调用function并没有等代码在主队列上执行完才继续。

所以在你的情况下,当调用async时,UI 线程完成他正在做的事情,调用viewWillLayoutSubViews ,做自动布局等等......当他完成并有时间时,他异步执行setContentOffset

然而,理论上它并不能保证它总是相同的顺序:UI 线程可能会在之前找到时间,或者可能被超额预订并且在viewDidAppear之前没有时间......但实际上,我认为你可以安全地假设它将是99.99% 的时间都是相同的订单。

注意:在其他情况下,您可以考虑使用DispatchQueue.main.sync ,它会说“尽快做,我在等你”。 然而,这可能是一个糟糕的想法,尤其是当您在 UI 线程中时:您将在 UI 线程中等待 UI 线程执行其他操作,并且您无法摆脱它 - 这是一个死锁。 更多细节在这里

暂无
暂无

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

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