NSFetchedResultsControllerDelegate动画删除错误的indexPath



前提:我有一个符合NSFetchedResultsControllerDelegateUITableViewController。我还有一个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之间的索引差异。它们最初应该是匹配的,如果你只删除最后一项应该没问题,但是任何其他的删除都会导致它们不同步。

最新更新