当使用 2 个相同的 NSIndexPath 调用 NSFetchedResultsChangeMove 时,如何保持选中的单元格?

How to keep a cell selected when NSFetchedResultsChangeMove is called with 2 identical NSIndexPath?

如果我单击一个单元格并且发生后台核心数据刷新,我的单元格将被取消选择。

经过调查,我的 NSFetchedResultsControllerDelegatecontroller:didChangeObject:atIndexPath:forChangeType:newIndexPath: 的实现被调用时使用了 NSFetchedResultsChangeMove 类型,但 indexPathnewIndexPath 是相同的(即相同的 row/section 值)。

NSFetchedResultsChangeUpdate 类型没有被调用。

我对 controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: 的实现是 Apple 文档中提供的典型实现。我相信切换自:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {

    ...

    switch(type) {

        ...

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

至:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {

    ...

    switch(type) {

        ...

        case NSFetchedResultsChangeMove:
            if (indexPath.section != newIndexPath.section || indexPath.row != newIndexPath.row) {
                [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            }
            break;
    }
}

会解决我的问题。

我的问题是:此修复是否正确,或者我是否遗漏了一些可以解释为什么我的更新属于 NSFetchedResultsChangeMove 类型的内容?

我的问题是我正在为与以前相同的 NSManagedObject 个实例赋值。即,如果 foo.bar 为 2,我将调用 API 并在我的对象上调用新的 foo.bar = 2 赋值。即使值相同,Core Data 仍在考虑值已更改。

我得到的是 NSFetchedResultsChangeMove 类型而不是 NSFetchedResultsChangeUpdate 类型,这仍然很奇怪,但是嘿。

我为解决这个问题所做的是:

if ([object.changedValues count] == 0) {
    // Reverting changed on object
    [context refreshObject:object mergeChanges:NO]
}

在每次更新结束时,而不是一个一个地比较属性。