在 UIAlertController Action 中关闭 UIViewController 会导致崩溃
Posted
技术标签:
【中文标题】在 UIAlertController Action 中关闭 UIViewController 会导致崩溃【英文标题】:Dismissing UIViewController in UIAlertController Action causes a crash 【发布时间】:2018-02-22 21:20:25 【问题描述】:我只有一个简单的 UIAlertController 并通过单击按钮显示它:
let alert = UIAlertController(title: "", message: NSLocalizedString("Are you sure you want to log out?", comment: ""), preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Sign Out", style: UIAlertActionStyle.default, handler: (alert: UIAlertAction) in
self.dismiss(animated: true, completion: nil) // CRASH
))
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
我想通过这个对话框操作来关闭我的控制器。
所以当我点击警报中的“退出”按钮时,我的应用程序崩溃了。
崩溃日志:
-[UICollectionViewData validateLayoutInRect:] 中的断言失败,/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/UICollectionViewData.m:435 2018-02-23 00:11:17.741531+0300 App[4681:1373962] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“UICollectionView 收到的单元格具有不存在的索引路径的布局属性: length = 2, path = 0 - 0'
但是!我在这个控制器中根本没有 CollectionView。
注意:如果我只使用一个简单的 self.dismiss(...) 而不使用此警报操作,那么我的控制器会被正常关闭。
注意 2: 我要关闭的控制器是一个 SplitViewController,我没有任何 CollectionViews。
注意 3: 我使用 self.present(splitVC, animated: true) 以简单的方式展示了我的 SplitViewController
有什么建议吗?
【问题讨论】:
SplitViewController 的呈现视图控制器是什么? 这很奇怪,我试图在这里重现..没有运气。看起来您的视图层次结构中有一些东西。关闭后立即出现的视图具有集合视图? @theCoderGuy UIViewController with CollectionView。 @GIJOW 是的,它有一个集合视图。但是,我又尝试了一次相同的设置和没有 UIAlertAction 的 VC,它按预期工作。 是的,我明白...只是想弄清楚您的环境。在这个拥有 CollectionView 的视图中,viewDidAppear
或 viewWillAppear
上是否有任何代码?
【参考方案1】:
问题解决了。
此崩溃是由 layoutAttributesForElements 引起的。我的缓存数组没有被清除,当 layoutAttributesForElements 被调用时出现崩溃。
如果你有一个自定义的 CollectionView 布局,那么你应该总是清除 UICollectionViewLayout 的 prepare() 中的缓存。
override func prepare()
cache = [UICollectionViewLayoutAttributes]()
...
这就是问题所在。
【讨论】:
以上是关于在 UIAlertController Action 中关闭 UIViewController 会导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中旋转 UIAlertController
从第一个 UIAlertController 打开第二个 UIAlertController