繁体   English   中英

Swift:致命错误:从TableView删除项目时数组索引超出范围

[英]Swift: fatal error: Array index out of range on deleting item from a tableview

我已经设置了一个表来从数据库中提取数据。 用户可以通过复选框(table.editing = true,iirc)和删除按钮从表(从而从数据库)中手动删除项目。 这可以一次完成,也可以一次完成。

不幸的是,每当我检查所有要删除的内容时,应用都会崩溃并显示以下错误:

致命错误:数组索引超出范围

如果我仅选择和删除一个或任意数量的表行,只要我不选择所有内容,就不会发生这种情况。

这是我的删除按钮代码:

func deleteButtonPressed(sender: AnyObject) {
    if (self.pureSteamFormView.tableCalibration.editing == true) {
        if (self.pureSteamFormView.tableCalibration.indexPathsForSelectedRows!.count >= 1) {
            for indexPath in self.pureSteamFormView.tableCalibration.indexPathsForSelectedRows!.sort({ $0.row < $1.row}) {
                let calibTable : FormSteamPurityCalibration = self.steamPurityCalibrationTableList[indexPath.row] /* <--- ERROR HERE */

                DatabaseManager.getInstance().deleteData("FormSteamPurityCalibration", "ID = \(calibTable.ID)")

                self.steamPurityCalibrationTableList.removeAtIndex(indexPath.row)
            }
            self.pureSteamFormView?.tableCalibration.reloadData()
        }
    }
}

据我所知,它正在尝试删除索引处的行,由于上一行也被删除了,所以该索引可能不再存在(?),但是我不确定。

我尝试放入以下代码:

self.steamPurityCalibrationTableList.removeAtIndex(indexPath.row)

在它自己的for循环块中,错误立即移到那里。

我还尝试完全删除removeAtIndex部分,依靠reloadData()也许自动更新表,但是它不起作用-数据已从数据库中删除,但仍保留在表中(尽管远离该视图并返回那里更新表格)。

有什么建议吗? 谢谢。

您的问题在于,您正在删除最低索引,而不是较大索引。 让我用一个例子来解释:

图片您的数组中有4个元素:

let array = ["Element1", "Element2", "Element3", "Element4"]

您正在尝试删除索引1和3中的元素:

for index in [1, 3] {
    array.removeAtIndex(index)
}

您的程序将首先删除索引1处的元素,剩下以下数组:

["Element1", "Element3", "Element4"]

在循环的第二遍,它将尝试删除索引3处的元素。该元素已不存在,因为它已移至索引2。

一种解决方案是先删除索引较大的元素,因此可以在代码中进行更改

for indexPath in self.pureSteamFormView.tableCalibration.indexPathsForSelectedRows!.sort({ $0.row < $1.row}) {

for indexPath in self.pureSteamFormView.tableCalibration.indexPathsForSelectedRows!.sort({ $0.row > $1.row}) {

更好的解决方案是对数据数组进行过滤,使其仅包含您希望保留的元素,因此,请不要:

for indexPath in self.pureSteamFormView.tableCalibration.indexPathsForSelectedRows!.sort({ $0.row < $1.row}) {
    let calibTable : FormSteamPurityCalibration = self.steamPurityCalibrationTableList[indexPath.row]
    DatabaseManager.getInstance().deleteData("FormSteamPurityCalibration", "ID = \(calibTable.ID)")
    self.steamPurityCalibrationTableList.removeAtIndex(indexPath.row)
}

你可以做:

self.steamPurityCalibrationTableList.filter {
    if let index = self.steamPurityCalibrationTableList.indexOf ({ $0 })
    {
        for indexPath in self.pureSteamFormView.tableCalibration.indexPathsForSelectedRows! {
            if indexPath.row == index { return false }
        }

        return true
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM