NSFetchedResultsController - 在创建新节时获得异常(更新:可能是删除节中的所有行...)

时间:2011-01-31 20:07:07

标签: iphone uitableview core-data nsfetchedresultscontroller nsoperation

我有一个带有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文档中提供的代码时(以及一些调整使其在我的视图中工作),它运行正常。

2 个答案:

答案 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;