我在使用Swift,iOS 8,Xcode 6 Beta 6中的tableView中删除一行时遇到一些麻烦。每当我尝试删除一行时,我都会遇到错误
断言失败 - [UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3302.3.1/UITableView.m:1581 2014-08-30 20:31:00.971班级目录[13290:3241692] ***终止应用程序 未被捕获的异常' NSInternalInconsistencyException',原因: '无效更新:第1部分中的行数无效 更新(25)后必须包含在现有部分中的行 等于之前该部分中包含的行数 更新(25),加上或减去插入或删除的行数 该部分(0插入,1删除)和加号或减号的数量 移入或移出该部分的行(0移入,0移出)。
我已经阅读了这个常见问题的所有答案,并且觉得我已经完成了建议的条件。项目似乎从数据模型中删除 - - 当我重新加载应用程序时,删除的项目从表中消失了 - 但是在相应的sqlite文件中似乎有一些残余,当然数学没有加起来。吐出indexPath的println显示正确的Section和Row。我很困惑。这应该是直截了当但我遗漏了一些愚蠢的我确定,我怀疑在数据模型删除。 Github上的完整项目。
func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
return fetchedResultController.sections.count
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return fetchedResultController.sections[section].numberOfObjects
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableViewMain.dequeueReusableCellWithIdentifier("CellMain", forIndexPath: indexPath) as UITableViewCell
let personForRow = fetchedResultController.objectAtIndexPath(indexPath) as Person
cell.textLabel.text = personForRow.fullName()
return cell
}
func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -> Bool {
return true
}
func tableView(tableView: UITableView!, editingStyleForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.Delete
}
func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {
println("section and row \(indexPath.section) \(indexPath.row) ")
if (editingStyle == UITableViewCellEditingStyle.Delete) {
let personForRow : NSManagedObject = fetchedResultController.objectAtIndexPath(indexPath) as Person
context?.deleteObject(personForRow)
context?.save(nil)
tableViewMain.beginUpdates()
tableViewMain.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade)
tableViewMain.endUpdates()
}
答案 0 :(得分:6)
使用Xcode Core Data Master-Detail模板项目轻松重现崩溃。作为一般规则,当您使用NSFetchedResultsController
时,您应该使用NSFetchedResultsControllerDelegate
(您已声明但不使用它)。
删除tableView:commitEditingStyle:forRowAtIndexPath:
方法中的这些行:
tableViewMain.beginUpdates()
tableViewMain!.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
tableViewMain.endUpdates()
将这些行添加到viewController类:
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableViewMain.beginUpdates()
}
func controller(controller: NSFetchedResultsController!, didChangeSection sectionInfo: NSFetchedResultsSectionInfo!, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
tableViewMain.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
tableViewMain.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
func controller(controller: NSFetchedResultsController!, didChangeObject anObject: AnyObject!, atIndexPath indexPath: NSIndexPath!, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath!) {
switch type {
case .Insert:
tableViewMain.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
case .Delete:
tableViewMain.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
case .Update:
return
//Should also manage this case!!!
//self.configureCell(tableView.cellForRowAtIndexPath(indexPath), atIndexPath: indexPath)
case .Move:
tableViewMain.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
tableViewMain.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade)
default:
return
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController!) {
tableViewMain.endUpdates()
}
这可以解决您的问题。
答案 1 :(得分:3)
我认为这只是一个缓存问题。您的fetchedResultController
不会自动重新获取结果,因为它会缓存结果。这意味着,当再次调用tableView:numberOfRowsInSection:
时,即使您删除了某个项目,结果计数仍会返回25。