使用 NSInferMappingModelAutomaticallyOption 更改核心数据中的属性类型
Posted
技术标签:
【中文标题】使用 NSInferMappingModelAutomaticallyOption 更改核心数据中的属性类型【英文标题】:Changing Attribute Type in Core Data with NSInferMappingModelAutomaticallyOption 【发布时间】:2013-07-06 06:29:49 【问题描述】:我有我的核心数据存储并使用标志“NSInferMappingModelAutomaticallyOption”,这样每当我对核心数据模型进行更改时,我首先会创建一个新的模型版本,并且对数据模型的更改会自动迁移。
但是,我需要更改我的一个实体的属性类型。当我这样做时,自动迁移似乎不起作用,并且在我尝试运行我的应用程序时出现 Core Data 错误。
任何设置方法以继续自动模型迁移?
【问题讨论】:
你得到了什么“核心数据错误”? 【参考方案1】:你不能为此使用轻量级迁移,所以它有点困难(感谢 Apple),但并非不可能
在 Xcode 7.1 中一步一步:
1.创建新模型版本:
-
选择您的
.xcdatamodeld
型号 -> Editor
-> Add model version ...
编辑新模型的实体attribute type
将当前模型版本更改为新版本(文件检查器)。您应该会看到绿色刻度线已移动。
2。自定义核心数据映射模型
New file -> Mapping Model
(核心数据 -> 映射模型)
选择模型的source
(来自模型)和target
(模型)版本
自定义映射模型包含以这种方式调用的实体映射:NameToName
。此文件中目标实体中已更改属性的更改值表达式反映您需要的:FUNCTION($entityPolicy, "<*transformingMethodName*>" , $source.<*attributeName*>)
- transformingMethodName:您将调用以转换属性类型的自定义方法。 (将在下一步定义它 - 等等)
- attributeName:你更改的属性名称
-
创建
<*EntityName*>TransformationPolicy
类作为NSEntityMigrationPolicy
的子类
实现上面定义的transformingMethodName
。 (在此处执行您需要更改属性类型的操作)。确保您也将此方法添加到头文件中
将此类注册为自定义实体迁移策略在映射模型中(Model.xcmappingmodel -> 文件检查器 -> 第三列 -> 自定义策略 -> 输入您的 TransformationPolicy 类的名称。)
【讨论】:
您有机会发布#3 的示例。如果我想更改 foo,在我的第一个模型中它是一个 Int,但希望它在我的第二个模型中是一个 Double,那么将 foo 从 Int 更改为 Double 的代码是什么样的?类 (EventTransformationPolicy) 中是否只有 1 个函数可以完成这项工作?谢谢 您好,这是一般指南。 transformingMethodName 只是指南的占位符。您必须创建自己的方法来转换属性类型并在 #3 中引用其名称。 @JakubTruhlář 我如何管理多个目标?【参考方案2】:轻量级迁移不支持属性类型更改:
为了使 Core Data 能够生成推断映射模型,更改必须符合明显的迁移模式,例如:
简单添加新属性 删除属性 非可选属性变为可选 可选属性变为非可选属性并定义默认值 重命名实体或属性
编辑
我假设您使用的是轻量级迁移。但正如斯科特指出的那样,也许你不是。如果你想使用自动迁移(这与轻量级迁移不同),你仍然可以通过提供映射模型来做到这一点。在这种情况下:
Core Data 将尝试在应用程序包中定位源模型和映射模型,并执行迁移。
但这种迁移不会是轻量级的。 Core Data 将打开两个存储——源和目标——并复制内存中的所有实体。所以应用所消耗的内存取决于存储中的数据量。
【讨论】:
虽然Wise Shepherd大概是指轻量级迁移,但是轻量级迁移和自动迁移并不是一回事。使用映射模型,迁移仍然可以自动发生(这就是NSMigratePersistentStoresAutomaticallyOption
的用途)。
加载商店时传递的选项是:@NSMigratePersistentStoresAutomaticallyOption : @(YES), NSInferMappingModelAutomaticallyOption : @(YES);
为了继续使用轻量级迁移,我可以增加模型版本并删除有问题的属性,然后再次增加模型版本并添加一个名称相同但类型不同的属性吗?
恐怕不行。自动迁移(无论是否轻量级)不支持渐进式迁移。例如,您有模型 1、2 和 3。您的商店文件是使用模型 1 生成的。现在您使用模型 3 运行应用程序。自动迁移将尝试从 1 到 3 查找映射模型。如果您指定 NSInferMappingModelAutomaticallyOption ,然后迁移将尝试推断映射模型。但是如果模型 3 中的属性类型与模型 1 不同,则无法推断模型。
可以进行渐进式迁移,但您必须手动控制迁移过程。以上是关于使用 NSInferMappingModelAutomaticallyOption 更改核心数据中的属性类型的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)