Core Data 轻量级迁移 - 现有实体是不是添加了新属性?

Posted

技术标签:

【中文标题】Core Data 轻量级迁移 - 现有实体是不是添加了新属性?【英文标题】:Core Data lightweight migration - do existing entities have new attributes added to them?Core Data 轻量级迁移 - 现有实体是否添加了新属性? 【发布时间】:2016-04-08 07:42:28 【问题描述】:

我有一个 Core Data 托管对象模型全部设置并在 ios 应用程序中工作,我正在使用 NSManagedObject 子类,这些子类是使用 [[MyEntityClass alloc] initWithEntity:description insertIntoManagedObjectContext:context]; 实例化的

我一直在阅读一些有关 Core Data 迁移的教程,以便为将来可能的应用程序更新做准备。对于我目前为这种特殊情况设想的更改,我相信轻量级迁移就足够了。我了解轻量级迁移将数据从旧数据模型映射到新版本。但是有一点我不清楚。如果持久存储包含迁移之前创建的 NSManagedObject 子类实例,这些对象是否会与模型一起修改以允许它们使用迁移中添加的属性?

我将举一个例子来确保我清楚我在问什么。假设我有一个名为的实体,使用经典示例 Person。 Person 具有以下属性:

firstname
lastname

我创建了一个名为aPersonPerson 实例,并将其插入到持久存储中。我可以使用aPerson.firstnameaPerson.lastname 访问aPerson 的属性。

现在我将dateofbirth 属性添加到托管对象模型,因此Person 实体包含以下属性:

firstname
lastname
dateofbirth

现在,如果我从持久存储中检索aPerson 并尝试访问aPerson.dateofbirth,会发生什么情况?我会因为aPerson 不包含dateofbirth 属性而收到无法识别的选择器错误,因为它是在添加该属性之前创建的?或者轻量级迁移是否会将dateofbirth 属性和访问器方法添加到已在持久存储中的所有Person 实例?

【问题讨论】:

【参考方案1】:

如果您将属性添加到新模型版本,则该属性必须是可选的,或者您必须指定默认值。否则,使用旧模型保存的持久存储将无法使用新模型验证。

在您的示例中,指定默认 dateofbirth 是没有意义的,因此您可以将该属性设为可选并处理它有时不存在的情况。

我找不到这方面的明确文档。您应该非常彻底地测试迁移。

【讨论】:

非常感谢,非常有帮助!所以,当你说处理不存在的属性时,会不会涉及到if ([myEntity respondsToSelector:@selector(myMigratedAttributeName))... 不,方法在类上,而不是实例上。您阅读该属性并查看它是否为nil methods are on classes, not instances - 是的,但respondsToSelector: 不会验证该属性是否存在于 NSManagedObject 子类中?如果实体子类是在数据迁移之前创建的,那么尝试访问添加的属性只会返回 nil,还是会导致无法识别的选择器异常? 它将返回nil。托管对象具有的属性来自其实体的属性,实体是托管对象模型的一部分。 嗯,好的。我假设托管对象完整地存储了它已经设置的任何属性,因此如果“旧”托管对象没有新版本实体的添加属性,应用程序就会崩溃。如果它只会返回 nil,那么这很好。非常感谢您的帮助!

以上是关于Core Data 轻量级迁移 - 现有实体是不是添加了新属性?的主要内容,如果未能解决你的问题,请参考以下文章

iOS Core Data 不执行轻量级迁移

Core Data 自动迁移不会在我的新模型中创建新实体

在 Core Data 迁移期间添加关系 - 自我参考

Core Data轻量级迁移错误

在 Core Data 中进行重量级迁移时尝试迁移 nil 属性值

考虑使用 Core Data 轻量级迁移的多个数据模型版本