【问题标题】:How to achieve logical deletion in UITableView with CoreData and NSFetchedResultsControllerUITableView中如何用CoreData和NSFetchedResultsController实现逻辑删除
【发布时间】:2012-06-05 11:29:46
【问题描述】:

我正在使用主/详细信息机制。 tableview 控制器使用 [controller:(NSFetchedResultsController *)controller didChangeObject:...] 来刷新相关行。 它适用于插入和删除。

现在我不想真正删除行,只是“隐藏”它们。

所以我在核心数据模型中添加了一个布尔值“已删除”,而我的主人使用谓词仅获取“已删除 = FALSE”。

在 [controller:(NSFetchedResultsController *)controller didChangeObject:...] 我需要:

  • 检查 NSFetchedResultsChangeUpdate。
  • 如果是这样,我可能需要“刷新”文件 fetchedResultController(不确定它是否可以检测到与谓词匹配的 managedObject 不再匹配),
  • 我需要从 tableview 中删除该行。

代码如下:

case NSFetchedResultsChangeUpdate:
    // This is fired by saving managedObject.deleted from FALSE to TRUE
    // ... so I would like to delete the corresponding row from the tableview
    // without reloading the full table.
    self.fetchedResultsController = nil;
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;

但它没有按预期工作,并且只是崩溃并显示错误消息:

2012-05-31 09:48:23.293 TableViewTest[32701:fb03] CoreData: error: 
``Serious application error.  
An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.
Invalid    update: invalid number of rows in section 0.  
The number of rows contained in an existing section after the update (7) 
must be equal to the number of rows contained in that section before the update (7),
plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) 
and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). 
with userInfo (null)

消息很清楚,NSFetchedResultsController 没有返回正确的计数。通过启用 CoreData 请求日志,在这个方法中,似乎还没有提交更改。

我尝试了不同的方法:

  • 确保 NSFetchedResults 确实发出请求(显式调用 fetch,删除缓存)。
  • 我尝试指定 [fetchRequest includesPendingChanges] 以包含尚未提交的更改

但我总是有同样的问题。 为什么它对插入和真正的删除有效(插入和删除没有提交但被 NSFetchedResultsController 看到)。

PS:为了说明这个特殊问题,我从 Xcode 模板创建了一个新项目(使用 CoreData + MasterController 选项)。你可以在 github https://github.com/arnauddelattre/TableViewTest 上找到它。您可以尝试添加一些行,然后选择一行并单击“逻辑删除”。

_

编辑:根据 Mundi 的回应 Mundi 建议我在托管上下文中调用 save 方法。 如您所见,我已经在调用 [controller didChangeObject] 的保存方法中。 因此,它导致在保存中调用保存。

对我来说奇怪的是,它似乎工作。但我害怕可能的副作用(因为在保存中调用保存)。这是实现我想要的“标准”方式吗?

而且我仍然不明白为什么这种行为与插入/真正删除不同。

【问题讨论】:

    标签: iphone ipad core-data nsfetchedresultscontroller


    【解决方案1】:

    您可以在将fetchedResultsController 设置为nil 之前保存(提交)NSFetchedResultsChangeUpdate 回调中的更改。

    【讨论】:

    • 保存是一项与数据相关的活动。更改获取的结果控制器是依赖于数据的 UI 相关活动。因此,如果尚未提交更改以通知他已获取结果控制器,则在回调中执行此操作是有意义的。我认为您不必担心保存“两次”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多