我有一个由NSFetchedResultsController支持的表视图 . 情况如下 . 我已经实现了"swipe to delete"一行 . 委托NSFetchedResultsController的方法和表视图的方法's are called. But the thing is, I don' t想要删除一个核心数据实体,我只想标记它的布尔标志,因为我在应用程序的其他部分需要这个实体,并希望表视图删除带动画的行 . 但是,根据错误消息,它与逻辑相反,如果您要更新实体,更新行,而不是删除它 . 有没有优雅的方法来实现它?或者唯一的选择是重新加载表?
Implementation of swipe to delete
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
Issue *issue = [self.fetchedResultsController objectAtIndexPath:indexPath];
[issue setHasBeenDeleted:[NSNumber numberWithBool:YES]];
[issue setPurchased:[NSNumber numberWithBool:NO]];
[self.managedObjectContext saveToPersistentStore:nil];
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id) anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
...
case NSFetchedResultsChangeUpdate:
[self.tableView deleteRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
break;
NSFetchedResultsControllerDelegate
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[self.tableView beginUpdates];
}
Error message
CoreData:错误:严重的应用程序错误 . 在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托中捕获到异常 . 无效更新:第0节中的行数无效 . 更新(5)后现有部分中包含的行数必须等于更新前该部分中包含的行数(4),加上或减去数字从该部分插入或删除的行(0已插入,1已删除)和加或减移入或移出该部分的行数(0移入,0移出) . 用户信息(null)
2 回答
在您提供给FRC的获取请求中,将此布尔值包含在谓词中 . 例如,
[NSPredicate predicateWithFormat:@"shouldDisplay = YES"]
. 然后,只要你想删除特定对象,只需将你的shouldDisplay(或你称之为的任何东西)设置为NO,然后你将收到controller: didChangeObject:
的一个带有NSFetchedResultsChangeDelete
更改类型的FRC委托回调 . 在此回调中,您将执行以下操作 .您的对象将保留在核心数据中,但由于您对布尔标志的谓词,它将从此特定表视图中过滤掉 .
编辑:您还需要实现两个FRC委托方法,以通知您的表视图开始和结束更新 . 这将纠正您收到的错误 . 像这样:
我无法让Pat Goley的解决方案起作用,尽管我可能没有正确实现它 . 经过一些实验,我提出的解决方案包含在一个回调方法中:
这样做的缺点是必须调用
performFetch()
,但没有它,'s crash city. For very large recordsets, an approach similar to Pat'可能是最好的 .