NSFetchedResultsController委托异常

Dan*_*iel 5 cocoa-touch core-data uitableview nsfetchedresultscontroller

我有一个应用程序,它使用表视图来显示我的核心数据的项目列表.我正在使用远程api,我在下拉表视图后更新了我的内容 - 这会触发对API的调用.

数据被检索,解析并插入/更新到我的核心数据中.

有时会得到一个错误,救了我的核心数据上下文之后...请注意,我没有使用多线程这就像我说的它似乎并不总是发生.

我真的很生气.看起来这个人有类似的问题,但我仍然无法用他的解决方案修复我的问题: CoreData错误让我发疯... CoreData:严重的应用程序错误.从NSFetchedResultsController的委托中捕获的异常

这是完整的错误:

2012-07-31 14:14:47.332 MyApp[2893:11303] 
*** Assertion failure in -[_UITableViewUpdateSupport _setupAnimationsForNewlyInsertedCells], 
/SourceCache/UIKit_Sim/UIKit-1914.84/UITableViewSupport.m:1133
2012-07-31 14:14:47.332 MyApp[2893:11303] CoreData: error: Serious application error.  
An exception was caught from the delegate of NSFetchedResultsController during a call to -
controllerDidChangeContent:.  
Attempt to create two animations for cell with userInfo (null)
Run Code Online (Sandbox Code Playgroud)

更新:

我有一个关于我的获取请求的谓词.为了似乎删除先前从API下载的对象以及新JSON结果中缺少的对象.我正在设置一个hideFromUser标志,这个保存在我的核心数据中.

如果此标志为YES,则它不会出现在表视图中.但是,如果没关系,那就确实如此.如果有任何改变,我也在更新该托管对象的信息.是否有可能我有一个先前设置为隐藏的对象...现在设置为显示,并且它还有一些新数据,这是否可能触发"单元格应该更新"和"单元格应该插入"?

更多我认为它似乎不太相关.

以下是我更新数据的方式:

1)我将相应类型的所有相关对象设置为"隐藏表单用户"(NSPredicate确保它们不在表视图中显示).

2)我从JSON数据中获得了一个NSArray.

3)循环每个项目,我的createABookOfClass:withJSON:方法查询书籍的核心数据(使用json字典中的ID),如果找不到,则创建一个新的.注意:此时,"隐藏用户标志"将被恢复.

4)一切都完成后,我保存.

[[DPLocalStore getInstance] hideFlagItemsOfType:NSStringFromClass([MyFavouriteBook class])];

NSArray * itemsJSON = [data mutableObjectFromJSONData];

[itemsJSON enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) {     
    [[DPLocalStore getInstance] createABookOfClass:[MyFavouriteBook class]
                                          withJSON:obj];
}];

NSError *error = nil;
BOOL didsave = [[DPLocalStore getInstance] save:&error];
Run Code Online (Sandbox Code Playgroud)

也许正在发生的事情是包含对象A的单元格已更新,它的更新:隐藏标志已更改.因此,我进入NSFetchedResultsController的委托想要更新该单元格的情况,并将其删除...因为谓词现在不对应于此对象......这听起来很可能......

Dan*_*iel 10

我想我可能已经找到了错误,因为我改变了它我没有遇到过这个问题所以我假设它没问题.

在我的实现中,controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:我在switch语句中有NSFetchedResultsChangeMove:

case NSFetchedResultsChangeMove:
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                     withRowAnimation:UITableViewRowAnimationFade];

    // Reloading the section inserts a new row and ensures that titles are updated appropriately.
    [tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section]
             withRowAnimation:UITableViewRowAnimationFade];
    break;
Run Code Online (Sandbox Code Playgroud)

由于它是在一个较旧的项目中使用的(我不是其中的一部分),我认为整个controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:实现都没问题,因为这实际上更像是一个模板而不是你会做任何定制的事情.

因此,在我在Apple开发者网站上再次阅读它之前,我并没有太多关注它.我注意到,如果NSFetchedResultsChangeMove你必须删除一个单元格,并将单元格插入新路径.然而,我没有真正意识到实现 - 删除单元格并重新加载该部分!

实际上我应该现在有以下内容:

case NSFetchedResultsChangeMove:
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                     withRowAnimation:UITableViewRowAnimationFade];
    [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                     withRowAnimation:UITableViewRowAnimationFade];
    break;
Run Code Online (Sandbox Code Playgroud)

就像我说的那样,自那以后我没有遇到任何问题.很想知道任何内部工作将对此负责 - 例外是"尝试为单元格创建两个动画".

感谢您的任何兴趣.