当我在我的 TabbarController 和 Viewcontrollers 中的两个选项卡之间切换时,这两个选项卡都包含一个 NSFetchResultsController。在我的一个 View Controller 中更新内容时出现以下核心数据错误:
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)
如果我尝试更新数据,我的 tableview 会变成白色并崩溃。
我的 -controllerDidChangeContent:看起来像这样:
Viewcontroller(我更新数据的 viewcontroller)。
-(void)controllerWillChangeContent:(NSFetchedResultsController*)controller
{
[self.productDetailTableView beginUpdates];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)controller
{
[self.productDetailTableView endUpdates];
}
-(void)controller:(NSFetchedResultsController*)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
UITableView *tableView = self.productDetailTableView;
switch (type) {
case NSFetchedResultsChangeInsert:
[tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
-(void)controller:(NSFetchedResultsController*)controller didChangeObject: (id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath
{
UITableView *tableView = self.productDetailTableView;
NSIndexPath *tvIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(indexPath.section + 1)];
NSIndexPath *tvNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:(newIndexPath.section + 1)];
indexPath = tvIndexPath;
newIndexPath = tvNewIndexPath;
switch (type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
}
}
Viewcontroller(此 Viewcontroller 的 TableView 变为白色并发生错误)。
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.cartTableView beginUpdates];
}
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.cartTableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:(ProductCell *)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray
arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView insertRowsAtIndexPaths:[NSArray
arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
break;
}
}
-(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
UITableView *tableView = self.cartTableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.cartTableView endUpdates];
}
如何解决这个问题并让“尝试使用 userInfo 为单元格创建两个动画”消失,发生这种情况的原因是什么?
最佳答案
这不是核心数据的问题,和核心数据完全没有关系。这是一个 TableView 问题。 CoreData 正在调用您的委托(delegate)方法,并且在其中 UIKit 正在抛出异常,因为您试图为同一个单元格设置两次动画。
为所有异常设置符号断点并尝试复制此行为。请注意,当 CoreData 解决合并冲突时,它会抛出完全正常的异常,但调试器会在这些异常上停止。继续前进,直到您的 tableview 异常。这将缩小问题所在的表格 View 的范围。
查看驱动单元格动画的数据。从您的代码看来,您似乎在设置动画之前修改了索引路径。这可能是问题的一部分。想象一下,如果您得到 NSFetchedResultsChangeMove 并且 tvIndexPath 等于 tvNewIndexPath 。这将产生您所描述的内容。
CoreData 绝对不是这里的问题,这是您的 tableview 动画。 CoreData 只是信使。
关于ios - NSFetchedResultsController-controllerDidChangeContent : - Attempt to create two animations for cell with userInfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22744888/