iOS CoreData 中的孤立对象

Posted

技术标签:

【中文标题】iOS CoreData 中的孤立对象【英文标题】:Orphaned objects in iOS CoreData 【发布时间】:2014-11-17 04:49:59 【问题描述】:

假设我有一个名为 Player 的 CoreData 实体类型,它与名为 PlayerPurpose 的实体类型具有一对一关系 (purpose)。为了完整起见,假设我们在PlayerPurpose 中有一个反向关系,称为parentPlayer。考虑以下 swift 代码:

// Assume we already have a player object in a NSManagedObjectContext called context:
player.purpose = NSEntityDescription.insertNewObjectForEntityForName("PlayerPurpose",
                 inManagedObjectContext: context) as PlayerPurpose;

// Later in the code, we set the value to nil (or we could have replaced
// it with another call to insertNewObjectForEntityForName)
player.purpose = nil;
// What happens to the previous playerPurpose object within the Managed Object Context?

我的问题:当原始 playerPurpose 对象在数据中的唯一引用设置为 nil(或替换为另一个对象)时,托管对象上下文中的原始 playerPurpose 对象会发生什么?

这与关系删除规则并没有真正的关系,因为我没有明确删除任何对象——我将其从任何有意义的关系中删除,使其成为孤立对象。

从 ARC 的角度来看(如果 PlayerPurpose 只是一个普通的非托管对象),原来的 PlayerPurpose 实例现在没有引用,因此可以从内存中清除它——但是在托管对象上下文中会发生什么? CoreData 是否将其识别为孤立对象并通过上下文将其删除?

如果不是,那么我假设如果要删除对它的所有引用,我必须小心删除通过上下文创建的任何托管对象。假设是这种情况,是否有一个好的模式可以用来确保从 NSManagedObjectContext 中清除孤立对象并且它们不再存储在持久存储中?

谢谢!

【问题讨论】:

【参考方案1】:

Core Data 在这种情况下不会自动删除对象,因为“孤立”是您的代码具有但 Core Data 无法识别的概念。没有理由仅仅因为它的一个关系是 nil 而删除 PlayerPurpose 对象。

确保删除PlayerPurpose 实例的最可靠方法是

    为您的实体创建自定义 NSManagedObject 子类(如果您还没有)。 在Player 子类上覆盖purpose 的setter 方法。如果新值为 nil,则删除旧值。

您也可以通过确保在适当的时间致电deleteObject: 来处理此问题。或者您可以运行一个清理步骤,在其中获取每个 PlayerPurposeparentPlayer 的值为 nil 并删除它们。

【讨论】:

感谢您的回答。这证实了我的猜想。

以上是关于iOS CoreData 中的孤立对象的主要内容,如果未能解决你的问题,请参考以下文章

CoreData(IOS)多列的唯一约束?

认识CoreData—初识CoreData

ios coredata 会在新版本中更改实体属性导致崩溃

如何存储数据库IOS程序[关闭]

孤立的核心数据对象没有被销毁

数据导入CoreData期间如何显示progressBar?