在 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 的视图中,viewDidAppearviewWillAppear 上是否有任何代码? 【参考方案1】:

问题解决了。

此崩溃是由 layoutAttributesForElements 引起的。我的缓存数组没有被清除,当 layoutAttributesForElements 被调用时出现崩溃。

如果你有一个自定义的 CollectionView 布局,那么你应该总是清除 UICollectionViewLayout 的 prepare() 中的缓存。

override func prepare() 
     cache = [UICollectionViewLayoutAttributes]()
     ...

这就是问题所在。

【讨论】:

以上是关于在 UIAlertController Action 中关闭 UIViewController 会导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

禁止UIAlertController的dimiss

UIAlertController 不会立即显示

如何在 Swift 中旋转 UIAlertController

从第一个 UIAlertController 打开第二个 UIAlertController

swift UIAlertController使用 UIAlertController的宽度 为270

iOS UIAlertController