DispatchQueue.main.asyncAfter 方法在特定调用中冻结 UI
DispatchQueue.main.asyncAfter method freeze UI in a particular call
我在修改对象的 属性 后调用 DispatchQueue.main.asyncAfter
方法(我用 KVO 触发它)。我只显示一秒钟的确认视图,然后 运行 一个在 UI 上做其他事情的块(弹出 viewcontroller)。问题是,当我从 UICollectionViewCell
调用此方法时工作正常,但是当我从应用程序中的另一个特定 UICollectionViewCell
调用此方法时,它会冻结。该方法在 UIView
.
的扩展中实现
public func showConfirmViewWith(title: String!, frame: CGRect? = screenBounds, afterAction: (() -> Void)?) {
let confirm = ConfirmationView(frame: frame!, title: title)
self.addSubview(confirm)
confirm.checkBox?.setCheckState(.checked, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) ) {
if afterAction != nil {
afterAction!()
}
confirm.removeFromSuperview()
}
}
当它冻结时,Dispatch 中的代码永远不会被调用,我在里面有一个断点,但永远不会到达那个点。
UDPATE
这是我暂停执行时的堆栈跟踪:
First time I paused the execution
我解决了这个棘手的错误。首先,DispatchQueue.main.asyncAfter 调用没有任何问题。该应用程序进入循环并且没有任何被锁定的迹象。我 运行 探查器发现一些约束的布局被一遍又一遍地调用。我在 collectionViewCell 中有一个 tableView,在完成对 asyncAfter 的调用时有一个动画。问题是覆盖方法 layoutSubviews 内部有一个 tableView.reloadData() ,所以每次我试图在带有动画的异步调用后退出时,都会调用 layoutsubviews 并且 reloadData() 一遍又一遍地触发。我不确定为什么 reloadData 在那里,但现在似乎工作正常。
我在修改对象的 属性 后调用 DispatchQueue.main.asyncAfter
方法(我用 KVO 触发它)。我只显示一秒钟的确认视图,然后 运行 一个在 UI 上做其他事情的块(弹出 viewcontroller)。问题是,当我从 UICollectionViewCell
调用此方法时工作正常,但是当我从应用程序中的另一个特定 UICollectionViewCell
调用此方法时,它会冻结。该方法在 UIView
.
public func showConfirmViewWith(title: String!, frame: CGRect? = screenBounds, afterAction: (() -> Void)?) {
let confirm = ConfirmationView(frame: frame!, title: title)
self.addSubview(confirm)
confirm.checkBox?.setCheckState(.checked, animated: true)
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1) ) {
if afterAction != nil {
afterAction!()
}
confirm.removeFromSuperview()
}
}
当它冻结时,Dispatch 中的代码永远不会被调用,我在里面有一个断点,但永远不会到达那个点。
UDPATE 这是我暂停执行时的堆栈跟踪:
First time I paused the execution
我解决了这个棘手的错误。首先,DispatchQueue.main.asyncAfter 调用没有任何问题。该应用程序进入循环并且没有任何被锁定的迹象。我 运行 探查器发现一些约束的布局被一遍又一遍地调用。我在 collectionViewCell 中有一个 tableView,在完成对 asyncAfter 的调用时有一个动画。问题是覆盖方法 layoutSubviews 内部有一个 tableView.reloadData() ,所以每次我试图在带有动画的异步调用后退出时,都会调用 layoutsubviews 并且 reloadData() 一遍又一遍地触发。我不确定为什么 reloadData 在那里,但现在似乎工作正常。