我已经设置了一个表来从数据库中提取数据。用户可以通过复选框(table.editing = true,iirc)和删除按钮手动删除表格(以及数据库)中的项目。这可以一次完成一个,也可以一次完成。
不幸的是,每当我检查所有内容以进行删除时,应用程序都会崩溃并出现以下错误:
致命错误:数组索引超出范围
如果我只选择并删除一个或任意数量的表行,则不会发生这种情况,只要我不选择所有内容。
这是删除按钮的代码:
typeof obj == 'function' || false
我可以想到,它正在尝试删除索引处的行,由于前一行也被删除,索引可能不再存在(?),但我不确定。
我尝试使用以下代码:
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()
}
}
}
在它自己的for-loop块中,错误立即移动到那里。
我还尝试完全删除self.steamPurityCalibrationTableList.removeAtIndex(indexPath.row)
部分,依赖于removeAtIndex
自动更新表,但它不起作用 - 数据从数据库中删除,但仍保留在表(尽管离开那个视图并返回那里更新表)。
有什么建议吗?感谢。
答案 0 :(得分:1)
这里的问题是你要在较大的索引之前删除最低的索引。让我用一个例子来解释:
图片中有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
}
}