ios - 没有 DispatchQueue.main.async 的意外布局行为
问题描述
有时,当自动布局或 UI 更改没有按照我的意愿执行时,我将代码包装到 a 中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
它告诉我它已经在主线程中,但它不能很好地完成动画,只是添加DispatchQueue.main.async
工作正常。我想知道究竟是什么DispatchQueue.main.async
使它起作用。因为我认为它只是让代码在主线程中执行,但如果它已经在主线程中执行,它不应该做任何事情......但是这样它工作正常并且不会产生布局问题。
(不同的代码和不同的应用程序发生在我身上,我一直在调试并告诉我已经在主线程中)。
我认为这可能是因为 dispatchQueue 产生了一点延迟,但它发生在更多不需要延迟的地方(Swift Animate duration not working in CGAffineTransform -> 今天我在没有 dispatchMainQueue 的情况下调试了这个问题,它是也在主线程中执行,但没有调度它就无法工作)
解决方案
简单地说,当您使用DispatchQueue.main.async
,时self.tableview.reloadData()
会在一小段延迟后被调用(因为 block 将在下一个循环中执行)。这就是为什么你有差异。
在这种情况下,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()
})
}
推荐阅读
- python - Flask - SQLAlchemy - 将 nullable=False 列添加到包含数据的现有表中
- reactjs - 你将如何在 React 中使用 useEffect 实现 shouldComponentUpdate?
- java - 如何通过 Angular 8 客户端程序 + CORS 问题使用 Spring Boot 应用程序的 REST API
- shopify - 将变体添加到 Shopify 购物车时的动态变体价格
- javascript - Jquery:如何在元素中隐藏元素?
- php - 在php中使用一个文件进行数据连接
- sql - 这个解决方案可以用case..when生成吗?
- ios - 广告 SDK 在没有应用程序 ID 的情况下初始化
- firebase - 如何过滤firebase cloud firestore上的id列表?
- reactjs - 将有效载荷从一个 saga 传递到另一个 saga