删除部分中的最后一个单元格后,iOS 应用程序崩溃

Posted

技术标签:

【中文标题】删除部分中的最后一个单元格后,iOS 应用程序崩溃【英文标题】:iOS app crashes after deleting the last cell in section 【发布时间】:2016-10-16 16:46:56 【问题描述】:

所以每次我尝试删除该部分的最后一个单元格时,我的应用都会崩溃。

例如,如果我的部分有 10 行,我可以毫无问题地删除它们,但最后一个会引发以下错误:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:无效的节数。更新后表视图中包含的节数(1)必须等于更新前表视图中包含的节数(3),加上或减去插入或删除的节数(0插入,0已删除)。'

我在这里搜索并找到了一些解决此问题的方法,但我尝试了所有方法并无法解决此问题,它仍然崩溃并抛出相同的错误。

我的代码的相关部分如下:

override func numberOfSections(in tableView: UITableView) -> Int 
    if (main_arr.count > 0 && sub_arr.count > 0) 
        self.numberOfSections = 3
     else 
        self.numberOfSections = 2
    

    return self.numberOfSections


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    if (section == 0) 
        return 1
     else if (section == 1 && main_arr.count > 0) 
        return main_arr.count
     else 
        return sub_arr.count
    



override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 
    return true


// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
    if editingStyle == .delete 

        switch indexPath.section 

        case 1:
            main_arr.remove(at: indexPath.row)

        case 2:
            sub_arr.remove(at: indexPath.row)

        default:
            print("default 001")
        

        tableView.deleteRows(at: [indexPath], with: .fade)

     else if editingStyle == .insert 
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    

编辑 1

我试图处理负责 numberOfSections 的全局变量,所以当我的任何 arrays.count == 0 时,它都会减 1,但它没有解决问题。

我完全理解错误消息,例如,如果我有 3 个部分,并且我删除了其中一个的全部内容,我应该删除一个部分并将其从数据源中删除。

【问题讨论】:

【参考方案1】:

问题是numberOfSections 在您删除行之前和之后返回不同的值,但是您没有删除任何部分。因此,您应该在 numberOfSections 中返回一个常量值,或者在 deleteRows 之外调用 deleteSections

要记住的主要内容如下:

UITableView 必须始终包含与您的数据源相同数量的行和节。

您不能只在 numberOfSectionsnumberOfRows 数据源方法中返回一个新值。每个更改都应使用删除/插入行(部分)方法进行补偿。反之亦然:如果您删除/插入 tableView,您必须在 dataSource 方法中返回相应的值。正如您的异常消息所述:

更新后表格视图中包含的节数 (1) 必须等于表中包含的节数 查看更新前(3),加减部分数量 插入或删除(0插入,0删除)

因为3+0≠1。在这种情况下,您应该删除两个部分以避免崩溃。

【讨论】:

比我快。 :) 那么,你是说如果是最后一行,我应该在tableView.deleteRows(at: [indexPath], with: .fade) 之后调用tableView.deleteSections(sections: IndexSet, with: UITableViewRowAnimation) 是的。如果您在删除某个部分后的某个时间点在某个部分中获得一个新单元格,您还需要插入一个部分。但我宁愿建议有 3 个部分,其中一些可能是空的。控制删除/插入会更容易一些,因为您将只使用行而不是部分和行。 嗯...让我试试看。【参考方案2】:

错误信息实际上很有帮助。它谈论的是sections - 它预计不会改变,但在您的操作之后它发现了不同的值。

基本上,UIKit 在调用您的代码、运行您的代码、然后检查新数字是否与您的操作一致之前会检查节数和行数。在您的情况下,它不会 - 因为您正在调用 deleteRows (这应该会减少给定部分的行数),但是您的 numberOfSections 委托现在给出了不同的结果。因此,您要么想调用deleteSections,要么保持sectionCount 不变。

顺便说一句,不禁止将0 作为部分的行数返回 - 也许这正是您想要的。

进一步说明:我认为将节数存储在实例变量中并不是一件好事。它使双重簿记。

【讨论】:

好的。我将尝试使用 3 个常量部分,看看我能从中得到什么,我会尽快反馈给你。

以上是关于删除部分中的最后一个单元格后,iOS 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

删除部分的最后一行后,应用程序崩溃

从 tableview 部分删除最后一行时,iOS 应用程序崩溃

在 UICollectionView 中删除单元格后,如何更新作为 UICollectionViewCell 一部分的按钮标签?

删除单元格后,collectionViewCell中的按钮中的索引错误

删除多个单元格后,uitableview 添加了一些行

从 UITableView 插入/删除单元格后的 IndexPath 错误