前提:我有一个符合NSFetchedResultsControllerDelegate
的UITableViewController
。我还有一个fetchedresultscontroller和managedobjectcontext作为控制器中的变量。我的tableView
显示了一个表,其中包含从获取的结果控制器中获取的核心数据对象的一部分。
我想实现的是滑动删除。选择删除的对象实际上被删除了,但是错误的indexPath正在被动画删除,我不知道为什么。我目前有以下方法,我认为是相关的:
// This method is being called in viewDidLoad, adding all of the CoreData objects to an array called fetchedResults.
func performFetch() {
do { try fetchedResultsController?.performFetch()
fetchedResults = fetchedResultsController?.fetchedObjects as! [Date]
} catch let error as NSError {
print(error.localizedDescription)
}
}
// tableViewDataSource methods
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let objectToDelete = fetchedResults[indexPath.row]
fetchedResultsController?.managedObjectContext.deleteObject(objectToDelete)
print("commitEditingStyle-indexPath = (indexPath)")
do { try managedContext.save()
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
// NSFetchedResultsControllerDelegate methods
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeObject object: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Delete:
if let indexPath = indexPath {
print("didChangeObject indexPath = (indexPath)")
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
default:
return
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.endUpdates()
}
可以看到,我打印了tableView:commitEditingStyle
方法和controller:didChangeObject
方法的indexPath。下面是两个print语句:
commitEditingStyle-indexPath = {length = 2, path = 0 - 3}
didChangeObject-indexPath = {length = 2, path = 0 - 0}
为什么didChangeObject
方法选择了错误的indexPath?当我滑动以删除对象时,对象在适当的indexPath处被删除(在本例中为3…),但是激活删除的表视图单元格是indexPath 0(表视图中的第一个单元格)。到底发生了什么事?
从代码中删除所有fetchedResults
的使用。您正在缓存FRC知道的初始对象集,但您不跟踪该缓存中的添加或删除。缓存也是一种内存浪费,因为你总是可以从FRC中得到你想要的东西,而且它还跟踪变化。
所以,你所看到的应该是一个随机的差异,这是由于缓存数组和FRC之间的索引差异。它们最初应该是匹配的,如果你只删除最后一项应该没问题,但是任何其他的删除都会导致它们不同步。