有时当自动布局或UI更改没有按照我的意愿执行时,我将代码包装到DispatchQueue.main.async
中并且它得到解决(例如):
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
DispatchQueue.main.async {
self.tableview.reloadData()
}
}
但是在没有Thread.current
的情况下使用(DispatchQueue
)调试此代码会告诉我已经在主线程中,但它不能很好地完成动画,只需添加{{1} } 工作良好。我想知道DispatchQueue.main.async
究竟是什么让它起作用。因为我认为它只是让代码在主线程中执行,但是如果它已经在主线程中执行它不应该做任何事情......但是这样它工作正常而没有创建布局问题。
(我遇到过不同的代码和不同的应用程序,我总是调试并告诉我已经在主线程中了。)
我认为这可能是因为dispatchQueue产生了一点延迟,但是在更多不需要延迟的地方发生了这种情况(Swift Animate duration not working in CGAffineTransform - >今天我调试了这个问题而没有dispatchMainQueue和它也会在主线程中执行,但如果没有调度则无法正常工作)
答案 0 :(得分:3)
简单地说,当您使用DispatchQueue.main.async
时,将在一小段延迟后调用self.tableview.reloadData()
(因为块将在下一个循环中执行)。这就是你有所不同的原因。
在这种情况下,当设备将旋转时执行viewWillTransition(to:with:)
。这意味着此时可能出现错误,设备尚未旋转。因此,如果您致电self.tableview.reloadData()
,可能会产生错误的结果。
为什么DispatchQueue.main.async
可以解决问题? - 这是因为DispatchQueue.main.async
在执行块之前给出了延迟,并且在此延迟后,self.tableview.reloadData()
将在设备之后调用完成旋转。这就是它给出正确结果的原因
使用animate(alongsideTransition:completion:)
执行此操作,您无需使用DispatchQueue.main.async
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: nil, completion: { (_) in
self.tableview.beginUpdates()
self.tableview.endUpdates()
})
}