如何取消删除 Core Data 中标记为删除的托管对象?

Posted

技术标签:

【中文标题】如何取消删除 Core Data 中标记为删除的托管对象?【英文标题】:How do I undelete a managed object marked for deletion in Core Data? 【发布时间】:2012-06-10 19:52:21 【问题描述】:

在 Core Data 中创建托管对象:

NSManagedObject *aManagedObject = [NSEntityDescription
insertNewObjectForEntityForName:@"Employee"
inManagedObjectContext:aContext];

要删除托管对象,请向其托管对象上下文发送消息。

[aContext deleteObject:aManagedObject];

该方法向一个ManagedObject 发送消息

- (void)prepareForDeletion

这是我的问题。我正在将此数据与外部数据库同步。我有一个名为“已删除”的属性。当一个对象第一次“删除”时,我想将“已删除”属性设置为 YES,然后将其同步到被删除的外部数据库。在未来某个日期,所有“已删除”==YES 实体都将过期并真正被删除。

在 prepareForDeletion 中我想测试一下是否:

dateSynced >= dateModified dateSynced “已删除”== 是

并真正删除对象,否则:

dateModified = 现在 “已删除”=是 并使其删除

现在有办法让它不被删除吗?

或者,我是否应该尝试使用 prepareForDeletion 覆盖 deleteObject 并创建一个新方法(例如 obsoleteObject 来设置“deleted”= YES 和 dateModified=Now 并且以后只使用 deleteObject 进行清除?

【问题讨论】:

【参考方案1】:

我最近实现了这样一个机制。

一旦实体被标记为已删除,您就不能延迟删除它。下次保存上下文时,它将被删除。您必须依靠其他东西来保持同步。

这是我的解决方案。我创建了一个持久的事件日志,其中一些是删除事件。当一个实体被标记为已删除时,我会创建一个相应的日志条目(实际上是在另一个上下文中,它保存在删除对象的上下文之前,以确保日志条目是最新的,并在执行实际删除之前保存)。稍后处理日志并将删除命令发送到服务器。如果保存了日志,但因为崩溃而删除的实体从未被删除,则下次启动应用程序时,处理日志,本地和远程同时删除实体,一切正常。

听起来很复杂,但实际上并不现实。

【讨论】:

【参考方案2】:

我认为,你不能这样做。我已经这样做了 - 在对象删除时我存储它的对象 ID(在我的情况下它是 guid 存储为文件)并且在同步时我将删除推送到服务器。

【讨论】:

【参考方案3】:

建议这样做,但是有一种方法可以从 Core Data 中“取消删除”一个对象。这可能不是你想要的。

只需使用要取消删除的对象调用insert(object) 就可以了。如果对象删除没有保存在上下文中,您必须先调用processPendingChanges()

重要提示:在取消删除之后,您还必须设置对象的所有属性,并取消删除在处理未决更改时可能已应用的所有级联删除(或当上下文已保存)。

请记住,这是一件危险的事情!你应该避免这样做。

我在 ios 10 上保存之前测试了取消删除。

【讨论】:

以上是关于如何取消删除 Core Data 中标记为删除的托管对象?的主要内容,如果未能解决你的问题,请参考以下文章

轻量级迁移后如何从 Core Data 中删除数据

如何从 Core Data 中删除数据

如何在 Swift 中从 Core Data 中删除数据时删除 UITableView 行?

如何在 Core Data iOS Swift 中删除和更新结构类型数组?

如何从 Core Data 中删除具有特定属性的项目?

删除时如何手动管理Core Data关系