Ios “如何修复”;n内部一致性异常';,原因:';无效更新:第0节中的行数无效。”;
我正在使用swift创建一个新的iOS应用程序,需要帮助才能让我的tableView删除数据。我使用核心数据将数据保存在一对多关系中,因此选定的实体会删除,但在更新tableView时会崩溃 我以前创建过应用程序,但这是我第一次使用一对多数据存储方法。我也在谷歌上搜索过这个解决方案,但都没有成功。这是我的tableView编辑风格的代码Ios “如何修复”;n内部一致性异常';,原因:';无效更新:第0节中的行数无效。”;,ios,swift,uitableview,core-data,crash,Ios,Swift,Uitableview,Core Data,Crash,我正在使用swift创建一个新的iOS应用程序,需要帮助才能让我的tableView删除数据。我使用核心数据将数据保存在一对多关系中,因此选定的实体会删除,但在更新tableView时会崩溃 我以前创建过应用程序,但这是我第一次使用一对多数据存储方法。我也在谷歌上搜索过这个解决方案,但都没有成功。这是我的tableView编辑风格的代码 if editingStyle == .delete { context.delete(items[indexPath.row]) do {
if editingStyle == .delete {
context.delete(items[indexPath.row])
do {
try context.save()
self.tableView.beginUpdates()
items.remove(at: indexPath.row)
self.tableView.deleteRows(at: [indexPath], with: .fade)
self.tableView.endUpdates()
} catch let error as NSError {
print("Could not save. \(error.localizedDescription)")
}
}
我希望行与核心数据中的实体一起删除,但实际上它只是删除实体,然后在尝试更新tableView时崩溃。具体地说,我认为当它调用“deleteRows”时会崩溃,因为它会给出错误:
Project Aurora[14179:303873]***由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:节0中的行数无效。”。更新(2)后现有节中包含的行数必须等于更新(2)前该节中包含的行数,加上或减去从该节中插入或删除的行数(0插入,1删除),加上或减去移入或移出该节的行数(0移入,0移出).'
更多代码:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let count = fetchedRC.fetchedObjects?.count ?? 0
return count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "itemsTable", for: indexPath) as! ItemsTableViewCell
items.append(fetchedRC.object(at: indexPath))
if items[indexPath.row].isComplete == true {
let attributeString = NSMutableAttributedString(string: items[indexPath.row].name!)
attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: NSMakeRange(0, attributeString.length))
cell.nameL.attributedText = attributeString
} else {
cell.nameL.text = items[indexPath.row].name
}
return cell
}
您使用的是一个
NSFetchedResultsController
,因此维护一个单独的数组(您的项
)数组不是一个好主意;只需使用对象(at:)
方法在需要时获取项目
在cellForRowAt:
-cellForRowAt:
中将项追加到items
数组中时,您也会遇到一个问题:对于给定的indexPath
,将多次调用cellForRowAt:
,并且无法保证调用cellForRowAt:
的顺序(例如,当您滚动表格视图时)
如果您使用的是NSFetchedResultsController
,您确实应该实现其委托,并使用委托方法更新表
去掉项
数组并使用以下内容:
extension ItemsTableViewController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
let newIndexPath: IndexPath? = newIndexPath != nil ? IndexPath(row: newIndexPath!.row, section: 0) : nil
let currentIndexPath: IndexPath? = indexPath != nil ? IndexPath(row: indexPath!.row, section: 0) : nil
switch type {
case .insert:
self.tableView.insertRows(at: [newIndexPath!], with: .automatic)
case .delete:
self.tableView.deleteRows(at: [currentIndexPath!], with: .fade)
case .move:
self.tableView.moveRow(at: currentIndexPath!, to: newIndexPath!)
case .update:
self.tableView.reloadRows(at: [currentIndexPath!], with: .automatic)
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.tableView.endUpdates()
}
}
您的删除代码应为:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "itemsTable", for: indexPath) as! ItemsTableViewCell
let item = fetchedRC.object(at:indexPath)
if item.isComplete == true {
let attributeString = NSMutableAttributedString(string: item.name ?? "")
attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: NSUnderlineStyle.single.rawValue, range: NSMakeRange(0, attributeString.length))
cell.nameL.attributedText = attributeString
} else {
cell.nameL.text = item.name
}
return cell
}
if editingStyle == .delete {
context.delete(fetchedRC.object(at:indexPath))
do {
try context.save()
} catch let error as NSError {
print("Could not save. \(error.localizedDescription)")
}
}
当您创建获取结果控制器时,请记住将
self
分配给fetchedRC.delegate
。尝试交换项。删除…
和beginUpdates
行。这也不起作用,我用完整错误更新了它,并删除了带有错误的注释,以减少混乱。您可以吗显示您的numberOfRows
和cellForRow
code?@Paulw11我用现在包含的numberOfRows和cellForRow更新了问题好的,谢谢。我实现了这一点,删除操作仍然有效,但似乎在删除行时没有调用扩展。为什么会这样?同样作为参考,我的视图控制器名称是“ItemsTableViewController”,如果这对扩展有帮助的话。我还更改了扩展名以扩展此视图。您是否将self
分配给fetchedRC.delegate
?此外,我在删除代码中遗漏了一个必需的更改-我已修复了itI,但没有。我如何将self
分配为fetchedRC.delegate
或分配到哪里?我注意到了这个要求并对其进行了更改,感谢您指出了这一点。假设您正在viewDidLoad
或类似程序中创建获取结果控制器,您只需说fetchedRC.delegate=self