你如何处理与NSFetchedResultsController的部分插入?

我有一个NSFetchedResultsController作为我的数据源,并且我在自定义的UITableViewController中实现了NSFetchedResultsControllerDelegate。 我正在使用sectionNameKeyPath将我的结果集分成多个部分。

在我的一个方法中,我将两个对象添加到上下文中,所有这些对象都位于新节中。 在我保存对象的那一刻,委托方法被正确调用。 事件的顺序:

// -controllerWillChangeContent: fires
[self.tableView beginUpdates]; // I do this

// -controller:didChangeSection:atIndex:forChangeType: fires for section insert
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]];

// -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath fires many times
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                withRowAnimation:UITavleViewRowAnimationFade]; // for each cell

// -controllerDidChangeContent: fires after all of the inserts
[self.tableView endUpdates];  // <--- Where things go terribly wrong!!!

在最后一次调用“endUpdates”时,应用程序总是崩溃:

Serious application error.  Exception was caught during Core Data change processing:
[NSCFArray objectAtIndex:]: index (5) beyond bounds (1) with userInfo (null)

似乎表更新与NSFetchedResultsController数据不同步,并且事情爆发了。 我正在关注NSFetchedResultsControllerDelegate上的文档,但它不起作用。 什么是正确的做法?

更新:我创建了一个展示这个bug的测试项目。 您可以在NSBoom.zip下载它


通过应用程序追踪,我注意到didChangeSection首先被调用,它插入了整个部分 - 然后重复调用didChangeObject。

问题在于,在didChangeSection中插入一个整体部分,然后在更新表视图之前,您正在将对象添加到同一部分。 这基本上是重叠更新的情况......(即使在开始/结束更新块中也是不允许的)。

如果您将单个对象插入注释掉,它将全部起作用:

 case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

如果你注释掉插入部分:它不起作用 - 但是我一直运行insertRowsInSections的运气不多,这可能是因为没有部分(我确信你是插入的原因开始的部分)。 您可能需要检测两种情况,以正确的粒度进行插入。

一般来说,我有更多的运气重新加载和插入整个部分比行,表视图似乎非常花费在我周围的工作。 您也可以尝试UITableViewRowAnimationNone,这似乎更经常地成功运行。


我有同样的问题。 我发现didChangeSection发射两次。 一次创建插入对象时,以及一次实际保存时。 对我来说,在保存被调用之前它不应该调用didChangeSection。 或者至少,将在创建对象时调用willChangeSection,并在保存时调用didChangeSection。

现在我正在研究NSManagedObjectContextDidSaveNotification观察者方法。 这不是NSFetchedResultsControllerDelegate协议的一部分,但您可以注册以接收它。 也许这只会在我实际调用保存时才被调用,而不是之前。

链接地址: http://www.djcxy.com/p/36095.html

上一篇: How do you handle section inserts with an NSFetchedResultsController?

下一篇: Access files on remote server