从NSFetchedResultsController提供的UITableView中删除行会导致我的应用程序崩溃。
错误是:
*断言失败 - [UITableView _endCellAnimationsWithContext:],/ SourceCache / UIKit / UIKit-2903.23 / UITableView.m:1330
* 由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第0节中的行数无效。更新后的现有部分中包含的行数(1)必须等于数字在更新(1)之前该部分中包含的行,加上或减去从该部分插入或删除的行数(插入0,删除1),加上或减去移入或移出该部分的行数(0)搬进来,0搬出去。'
我只想滑动删除。我的删除代码如下:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView beginUpdates];
SequenceData *sd = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.managedObjectContext deleteObject:sd];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
}
我的NSFetchedResultsController的设置就像Ray Wanderlich的教程(http://www.raywenderlich.com/999/core-data-tutorial-for-ios-how-to-use-nsfetchedresultscontroller)
行数由:
决定- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id sectionObjects = [[self.fetchedResultsController sections] objectAtIndex:section];
NSInteger nbObjects = [sectionObjects numberOfObjects];
return nbObjects;
}
看起来fetch没有更新(行数不变)。我是否需要取自己(这不是由fetch控制器处理)?
这里显然有一些基本的东西。不要犹豫,建议基本答案。
我首先用控制器实现了这个:didChangeObject:...方法。错误是一样的,但有些细节不同。
修改 我相信我的问题是固定的。这两个答案(来自CX和Martin)帮助我找到了答案。马丁得到了答案,因为解释有助于我更好地理解......
答案 0 :(得分:12)
不要打电话
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
如果使用获取的结果控制器。仅使用
删除对象[self.managedObjectContext deleteObject:sd];
然后自动调用获取的结果控制器委托方法 didChangeObject:
,
并且调用deleteRowsAtIndexPaths:
。
因此,在您的情况下,该行被删除了两次,这导致了异常。
请注意,此处不需要beginUpdates
/ endUpdates
。
答案 1 :(得分:4)
如果要删除行,则只需删除managedObject。
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.managedObjectContext deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
// handle error
}
}
删除托管对象会触发NSFetchResultController
委托方法,并会更新tableView
。
修改强>
您应该实现NSFetchResultController委托方法
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{
switch(type) {
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
////
default:
break;
}
因为当您使用NSFetchedResultsController等数据源时,所有更改都必须来自那里,而您的表只反映它们。