我在表视图中使用核心数据模型时遇到问题。在表视图的commitEditingStyle:delegate方法中,我首先删除模型的对象,然后删除表视图中的相应行,类似于:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.managedObjectContext deleteObject:[self coreDataObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
}
但是这会在UITableView中引发NSInternalInconsistencyException,因为numberOfRowsInSection:delegate方法返回错误的行数,因为Core Data对象尚未被删除。
我如何解决这个“官方方式”?还是最好的方式?
我是否必须跟踪NSManagedObjectContextObjectsDidChangeNotification通知并等待相应的删除通知?这是可行的,但可以让你很烦恼。
我是否只是等待并希望它在一段时间后被删除?我已经测试了插入[self performSelector:withObject:afterDelay:]来延迟删除表视图行。它甚至可以在0.0延迟时工作。我假设Core Data框架在当前运行循环结束后删除了对象,但是这有保证吗?它也可能只是纯粹的巧合。
还有其他方法来处理这种情况吗?对于像deleteObject这样的块完成API本来不错:withCompletionHandler:。
有什么想法吗?
/Påhl
答案 0 :(得分:0)
我假设你使用FetchedResultsController
用核心数据对象填充你的表。所以我们的想法是你需要实现以下方法。
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
}
在commitEditingStyle:
中,您只需从managedObjectContext
中删除该对象,然后让didChangeObject
委托为您处理表格修改。
didChangeObject
的示例实现可以在这里找到:
Apple's document
答案 1 :(得分:0)
显然,您已经自己解决了问题,但是代码中的问题是缺少从数据源“删除”对象的部分。 在
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath`
你必须把:
if (editingStyle == UITableViewCellEditingStyleDelete) {
// delete obj from the context
[self.managedObjectContext deleteObject:[self coreDataObjectAtIndex:indexPath.row];
// REMOVE obj from the dataSource (dataSource is your NSArray or NSMutableArray where are stored the objects
[dataSource removeObjectAtIndex:indexPath.row];
// then refresh the tableView
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}