NSManagedObject prepareForDeletion 中的 self.managedObjectContext == nil 有啥意义?

Posted

技术标签:

【中文标题】NSManagedObject prepareForDeletion 中的 self.managedObjectContext == nil 有啥意义?【英文标题】:What's the point of self.managedObjectContext == nil in NSManagedObject prepareForDeletion?NSManagedObject prepareForDeletion 中的 self.managedObjectContext == nil 有什么意义? 【发布时间】:2013-08-03 22:44:33 【问题描述】:

我有一个提醒实体需要在删除某个实体 B 时更新其date 属性。我花了几天时间编写代码,认为我可以在删除时在托管对象子类中做一些有用的事情。我试过了

- (void)willSave

if (self.isDeleted) 
    // use self.managedObjectContext

上下文为零。那里的关系也破裂了。很公平。

所以...我开始为prepareForDeletion 编写繁琐的代码来规避对象尚未被删除的事实,但随后Core Data 将self.managedObjectContext == nil 扔在我的脸上。文档说这是我“在关系破裂之前”做事的地方。那么如果self.relationshipA.managedObjectContext 是可访问的(正如文档所建议的那样),self.managedObjectContext == nil 的意义何在?更重要的是,为什么我尚未删除的对象没有它的上下文?

我阅读了关于该问题的评论 here

它不是“错误”,而是“拒绝”,上下文已经拒绝了您的对象(他被删除并且保存已提交到数据库),因此您的对象被拒绝了。不要保存在正在更改的方法和对象中,因为无论如何应该在操作之后提交/保存保存。 – 丹·雪莉 5 月 21 日 19:05

我的代码是:

[moc deleteObject:obj]
[moc save:NULL]

当我删除保存操作时,我的self.managedObjectContext 存在于prepareForDeletion 中。也就是说,直到自动保存,当它再次为零时。可能是因为父上下文也删除了它,然后由 UIManagedDocument 保存。

我开始认为我唯一的选择是创建一个自定义删除方法(直到 Core Data 级联删除,在这种情况下它不会被调用),或者创建一个新类来监听 NSManagedObjectContextDidSaveNotification .

更新:

用户想要与一个人保持联系,如果没有联系,想要在一定时间间隔后(存储在 ContactWish 中)得到提醒。我想要完成的是,当某个人的最新 ContactOccasion 被删除时,相应的场合->person->wish->reminder 会更新(使用间隔)。

由于这对我来说是一次学习经历,我想找到正确的方法(一种适用于级联删除等的方法),而不仅仅是在我的代码中[MOContext deleteObject:occasion] 的每个位置手动调用更新。欢迎提出建议。

(提醒实体也已准备好更多手动使用)

【问题讨论】:

【参考方案1】:

Reminder 实体管理其日期属性不是更合乎逻辑吗?它可以“监听”(可能通过changedValues:)其关系实体被删除并执行更新。

这似乎更一致,因为B 实体不应该真正关心Reminder 实体更新的逻辑。

编辑 根据下面的讨论并基于我的观点,您不能使用更新逻辑过多地加载数据库级联删除模型:

您可以引入一个您设置和侦听的属性来进行更改,而不是对删除做出反应。

我真的不明白依靠核心数据删除机制比编写自己的“deleteOccasion”方法来处理这个逻辑更容易或更优雅。

【讨论】:

我明白你的意思,我也不愿意把提醒逻辑放在不属于它的地方(现在我有一个单独的实体,代表用户希望自动更新提醒。最好代码将位于那里)。我看到的问题是这些是托管对象,所以我不能真正使用它们来监听任何东西,因为它们的生命周期不是由我管理的。在我明确地获取它们并保持强引用之前,我不能认为它们存在是理所当然的。如果尚未获取相关提醒,会发生什么(在您的情况下)? 会自动获取。我认为您描述的情况和我的设置可以保证您要更改的对象在那里。 好吧,我想我还是不明白 ;) 你的意思是使用 KVO 收听reminder.changedValues 属性吗? (Reminder 和 B 实体之间没有直接关系)我能做的最好的是reminder.person.B,这意味着我可以听reminder.person.changedValues。每当person.changedValues 更改时,这真的会获取相关提醒吗? 不确定您要完成什么。肯定有比你描述的更好的设置。 我不知道我在问题中遗漏了哪些重要部分,但请随时询问任何遗漏的细节。实际上我在描述很多事情——两次失败的尝试和两个不太理想的解决方案。如果您知道第三种解决方案,我将不胜感激。或者,如果有人可以帮助我了解如何确保在 prepareForDeletion 中始终有一个 MOContext,那么也许我可以通过这种方式解决问题。

以上是关于NSManagedObject prepareForDeletion 中的 self.managedObjectContext == nil 有啥意义?的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObject 故障/无法获得由 NSManagedObject 处理的“原始”对象

NSManagedObject - NSSet 被删除?

如何根据现有的 NSManagedObject 值在 NSManagedObject 派生类中设置默认值?

属性作为“当前 NSManagedObject”的视图控制器中的 NSManagedObject

创建新的 NSManagedObject 并将其分配给新的 NSManagedObject *有时*会失败

将 NSManagedObject 与另一个 NSManagedContext(多线程)中的“相同”NSManagedObject 合并