我有一个带有TableView和NSFetchedResultsController的视图。 我正在使用ASINetworkQueue(NSOperationQueue的子类)和ASIHTTPRequest的子类(后者又是NSOperation的子类)来下载JSON提要,解析它并将相应的实体插入到Core Data中。 因此,在ASIHTTPRequest子类中,我有第二个NSManagedObjectContext来保持所有线程安全和好。
一切都很好,每10秒左右我的后台获取/导入火灾,创建新实体并保存到Core Data存储中。 NSNotification传播到ViewController和NSFetchedResultsController,新的行出现在TableView中。
当JSON包含具有新键值的实体(让我们称之为“sectionID”)时出现问题 - 例如sectionID == 2而不是sectionID == 1(你得到它吗?)。
此时,NSFetchedResultsController应该让表视图创建一个新的部分,但我得到一个例外:
Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. *** -[NSArray initWithObjects:count:]: attempt to insert nil object at objects[0] with userInfo (null)
Assertion failed: (_Unwind_SjLj_Resume() can't return), function _Unwind_SjLj_Resume, file /SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c, line 326.
这是我的NSFetchedResultControllers委托方法的代码:
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[[self eventTable] beginUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
NSIndexSet* set = [NSIndexSet indexSetWithIndex:sectionIndex];
switch (type) {
case NSFetchedResultsChangeInsert:
[[self eventTable] insertSections:set withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[[self eventTable] deleteSections:set withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView* tv = [self eventTable];
switch (type) {
case NSFetchedResultsChangeInsert:
[tv insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tv deleteRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self tableView:tv configureCell:[tv cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[[self eventTable] endUpdates];
}
有关导致异常的最新消息吗?提前谢谢!
更新2011-02-03 不确定在创建新节目时是否发生错误,或者删除旧节目时是否发生错误。我几乎认为当删除一节中的所有行时会发生这种情况,但由于某种原因控制器:didChangeSection:atIndex:forChangeType未被调用。 有类似经历的人吗?
更新2011-02-08 我想我解决了。问题是在确定是否删除行/部分时必须考虑一些额外的条件。 使用Apple文档中提供的代码时(以及一些调整使其在我的视图中工作),它运行正常。
答案 0 :(得分:3)
我想我解决了。问题是在确定是否删除行/部分时必须考虑一些额外的条件。使用Apple文档中提供的代码时(以及一些调整使其在我的视图中工作),它运行正常。
更新2011-03-22
基本上我使用了与SafeFetchedResultsController中相同的方法。
答案 1 :(得分:0)
我不知道这是否是您的错误的原因,但您在委托方法中缺少NSFetchedResultsChangeMove案例。
case NSFetchedResultsChangeMove:
[changedTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[changedTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;