UITableView CoreData 断言失败
Posted
技术标签:
【中文标题】UITableView CoreData 断言失败【英文标题】:UITableView CoreData Assertion Failure 【发布时间】:2012-10-05 21:36:44 【问题描述】:当我的 iPhone 应用程序崩溃时,我在控制台中收到此错误:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-2372/UITableView.m:1070
当到达这行代码时它崩溃并给我这个:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[tableView endUpdates];
关于我的应用的一些细节以及我是如何做到这一点的。我有一个带有表格视图的视图控制器,它显示我的核心数据对象。我有这个视图设置来显示来自两个实体的数据,所以表部分 1 显示来自实体的对象,然后部分 2 显示来自我的第二个实体的对象。
这就是我的问题开始的地方。虽然这已经很好地解决了,但我可以推送我的下一个视图控制器,并将对象添加到我的第一个实体并立即弹出回我的 tableviewcontroller 没有问题。但是,如果我尝试将对象添加到第二个实体,则在返回到我的 tableviewcontroller 时,它会崩溃,如上所述。
我不知道是什么原因造成的,所以我不确定从哪里开始寻找。
来自控制台的一些额外错误信息:
CoreData:错误:严重的应用程序错误。在调用 -controllerDidChangeContent: 期间,从 NSFetchedResultsController 的委托中捕获了异常。无效更新:第 0 节中的行数无效。更新后现有节中包含的行数 (2) 必须等于更新前该节中包含的行数 (2),加上或减去数字从该部分插入或删除的行数(1 插入,0 删除)加上或减去移入或移出该部分的行数(0 移入,0 移出)。与 userInfo (null)
代码:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
// Return the number of rows in the section.
NSInteger rows;
id <NSFetchedResultsSectionInfo> sectionInfoAccounts = [[fetchedResultsControllerAccounts sections] objectAtIndex:0];
id <NSFetchedResultsSectionInfo> sectionInfoCosts = [[fetchedResultsControllerCosts sections] objectAtIndex:0];
if (section == 0) rows = [sectionInfoAccounts numberOfObjects];
else if (section == 1) rows = [sectionInfoCosts numberOfObjects];
return rows;
【问题讨论】:
Xcode 应该打印出更多关于断言失败的信息。编辑您的帖子以包含它打印的所有内容。 这就是我在控制台中得到的所有内容。 设法获取更多错误信息。检查我的问题。 注意,错误提示“第 0 节中的行数无效”。但是,当我尝试在第 1 节中插入一行时,我只会遇到此崩溃。我没有得到的另一个小混乱,它在某处获得了错误的索引? 即使您只修改了第 1 部分,表格视图仍然可以询问第 0 部分。您的数据源和委托必须准备好返回有关任何部分的正确信息。 【参考方案1】:您正在为表视图使用 2 个获取的结果控制器:一个 FRC 用于表部分 0,一个 FRC 用于表部分 1。我在这里有点猜测,但可能是错误在
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
如果为第二个 FRC 调用该函数,则 indexPath
/newIndexPath
的节部分为 0(因为 FRC 只有一个节)。但是对应的表节是1。
因此,在调用insertRowsAtIndexPaths:...
、insertRowsAtIndexPaths:...
等之前,您必须将 FRC 索引路径映射到表视图的索引路径。
以插入事件为例:
NSIndexPath *newIndexPath1 = [NSIndexPath indexPathForRow:newIndexPath.row inSection:1];
[self.tableView insertItemsAtIndexPaths:@[newIndexPath1]];
否则第二个实体的新对象将作为第一个表视图部分的行插入,这会导致不一致异常。
【讨论】:
这实际上很有意义,谢谢。我已将if (controller == fetchedResultsControllerCosts) newIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:1];
添加到上述方法中,它停止了我看到的错误。但是,现在这会导致在配置单元格时到达Cost *cost = [fetchedResultsControllerCosts objectAtIndexPath:indexPath];
时出现数组对象越界错误。
原来我只需要更改那里的部分,这次为 0。因为对象在 FRC 的第 0 部分,但在表格的第 1 部分。以上是关于UITableView CoreData 断言失败的主要内容,如果未能解决你的问题,请参考以下文章
UITableView _endCellAnimationsWithContext:无故断言失败
断言失败 -[UITableView _endCellAnimationsWithContext]