[英]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.