2009-10-13 67 views
0

我有一个NSFetchedResultsController作为我的数据源,并且我在自定义的UITableViewController中实现了NSFetchedResultsControllerDelegate。我使用sectionNameKeyPath将我的结果集分成多个部分。你如何处理与NSFetchedResultsController的部分插入?

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

// -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上的文档,但它不起作用。什么是正确的做法?

更新:我已经创建了一个展示此错误的测试项目。你可以下载它:NSBoom.zip

回答

1

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

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

如果您注释掉单个对象的插入,一切的工作:

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

如果您注释掉部分插入:,这是行不通的 - 但我有运气少用所有的工作insertRowsInSections时间,而且很可能是因为没有部分(我相信这是为什么你插入该部分开始)。您可能需要检测两种情况,以正确的粒度进行插入。

一般来说,我有更多的运气重新加载和插入整个部分比行,table view对我来说似乎非常fiddly围绕那些工作。您也可以尝试UITableViewRowAnimationNone,它似乎更经常地成功运行。

+0

谢谢!这一观察(双重更新)让我想出了一个我可以使用的解决方法。 – 2009-10-14 12:36:58

0

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

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

相关问题