我有一个应用程序,它使用表格视图显示我的核心数据的项目列表。我正在使用远程api,我在下拉表视图后更新了我的内容 - 这会触发对API的调用。
检索,解析数据并将其插入/更新到我的核心数据中。
我有时在保存我的核心数据上下文后出错...请注意,我没有使用多个线程,就像我说它似乎并不总是发生。< / p>
我真的很生气。看起来这个人有类似的问题,但我仍然无法用他的解决方案修复我的问题: CoreData error driving me crazy... CoreData: Serious application error. An exception caught from delegate of 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)
更新:
我的抓取请求有一个谓词。为了似乎删除先前从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];
可能正在发生的事情是包含对象A的单元格已更新,它的更新:隐藏标志已更改。因此,我进入NSFetchedResultsController的委托想要更新该单元格的情况,并将其删除...因为谓词现在不对应于此对象......这听起来很可能......
答案 0 :(得分:10)
我想我可能发现了错误,因为我改变了它我没有遇到过这个问题,所以我假设它没问题。
在我controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
的实现中,我在NSFetchedResultsChangeMove
的switch语句中有这个:
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;
由于它在较旧的项目中使用(我不是其中的一部分),我认为整个controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
实现都没问题,因为这实际上更像是一个模板,而不是你将做任何自定义的事情。
因此,在我在Apple开发者网站上再次阅读之前,我并没有太多关注它。我注意到,如果是NSFetchedResultsChangeMove
,您必须删除一个单元格,并将单元格插入新路径。然而,我没有真正意识到实施 - 删除单元格并重新加载该部分!
实际上,我应该现在拥有以下内容:
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
就像我说的那样,自那以后我没有遇到任何问题。很想知道任何内部工作将对此负责 - 例外是“尝试为单元格创建两个动画”。
感谢您的任何兴趣。