核心数据:何时是deleteObject:完成?

时间:2011-10-04 09:13:36

标签: ios core-data

我在表视图中使用核心数据模型时遇到问题。在表视图的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对象尚未被删除。

我如何解决这个“官方方式”?还是最好的方式?

  1. 我是否必须跟踪NSManagedObjectContextObjectsDidChangeNotification通知并等待相应的删除通知?这是可行的,但可以让你很烦恼。

  2. 我是否只是等待并希望它在一段时间后被删除?我已经测试了插入[self performSelector:withObject:afterDelay:]来延迟删除表视图行。它甚至可以在0.0延迟时工作。我假设Core Data框架在当前运行循环结束后删除了对象,但是这有保证吗?它也可能只是纯粹的巧合。

  3. 还有其他方法来处理这种情况吗?对于像deleteObject这样的块完成API本来不错:withCompletionHandler:。

  4. 有什么想法吗?

    /Påhl

2 个答案:

答案 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];
  }