NSFetchedResultsController:删除1行崩溃的应用程序

从NSFetchedResultsController提供的UITableView中删除一行会导致我的应用程序崩溃。

错误是:

*断言失败 – [UITableView _endCellAnimationsWithContext:],/ SourceCache /UIKit/UIKit-2903.23/UITableView.m:1330
*终止应用程序,由于未捕获exception“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; } 

它看起来像提取没有更新(行数不变)。 我是否需要取回自己(这是不是由取得控制器的照顾)?

显然这里有一些基本的东西。 不要犹豫,提出基本的答案。

我首先用controller:didChangeObject:…方法实现了这一点。 错误是一样的,但有些细节不同。

编辑我相信我的问题是固定的。 这两个答案(从CX和马丁)帮助我find它。 马丁得到了答案,因为这些解释让我明白了一点点…

不要打电话

 [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 

如果您使用提取的结果控制器。 只有删除对象

 [self.managedObjectContext deleteObject:sd]; 

获取的结果控制器委托方法 didChangeObject:然后自动调用,并调用deleteRowsAtIndexPaths:

所以在你的情况下,该行被删除了两次,并导致了exception。

请注意,这里不需要beginUpdates / endUpdates

如果你想删除一行,你只需要删除managedObject。

 if (editingStyle == UITableViewCellEditingStyleDelete) { [self.managedObjectContext deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; NSError *error = nil; if (![self.managedObjectContext save:&error]) { // handle error } } 

删除托pipe对象触发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这样的数据源时,所有的改变都必须来自那里,你的表只反映它们。