Coredata 的 CodeGen 'manual/none + create NSManagedObject subclass' 与 'category/extension' 之间的功能差异是什么
What are the functional differences between Coredata's CodeGen 'manual/none + create NSManagedObject subclass' vs. 'category/extension'
我读过 and read this 很棒的教程。还有一些问题。
相同点是:
- 我可以随心所欲地自定义这两个 class。
- 我可以添加新属性或删除或重命名属性。即对于
category/extension
它将在新构建时更新(在派生数据中),并且在 manual/none
的情况下它将保持 class 文件不变并更新文件导航中的扩展名即我不会以重复文件结束。这都是由 Xcode 处理的,因为它们标有预处理器 @NSManaged
- 不允许将
@NSManaged public var name: String?
之类的内容直接转储到现有的 NSManagedObject
子 class 中。我尝试执行 entity.name = "John"
但出现以下错误:reason: '-[SomeEntity setName:]: unrecognized selector sent to instance 0x60400009b120'
。我相信这是合理的。我认为如果不使用核心数据模型编辑器,就不会创建 setter/getter 访问器方法。
区别是:
- 对于
Category/Extension
,您只需自己创建 class 并添加您需要的任何额外 functions/properties。
对于Category/Extension
,属性是在派生数据中创建的,这就足够了。因为您永远不需要查看该文件。它的存在足以让事情正常进行。
特别是在对您的 NSManaged 属性进行 更改 的上下文中:
正在更改 属性 类型,例如NSDate
到 Date
只允许 Manual/None
。示例 here
- 改变类型的可选性,例如
String?
到 String
只允许 Manual/None
。示例 here
更改 属性 访问级别,例如从 public
到 private
只允许 Manual/None
。示例 here
话虽如此,但还是有显着差异 if 我选择 Manual/None
codegen 而 不选择 select 'create NSManagedObject subclass'。在这种情况下,我已经开始自己编写所有代码(来自 NSManagedObject 的 subclass 并为每个 属性 编写 NSManaged)...或者如果我不自己编写所有代码,那么我仍然可以 access/set 使用 KVC 的字段很尴尬!
简而言之,我只是想弄清楚使用 Manual/None
可以获得的全部功能。
问题: 除了我需要知道的 9 个 注释 之外,还有一个重要的 问题 将是:我如何将 NSDate
更改为 Date
或将可选更改为非可选而不破坏我的 NSManagedObject class 和我的对象图之间的映射NSDate
属性 到 String
确实中断了!!这是否与保证在 Swift 和 Objective-C 之间投射的东西有关,即可以通过 as
投射的东西——没有 ?
或 !
?
解决您的每条笔记并考虑代码生成设置为 Manual/None
和 Category/Extension
的情况:
- 是的,无论哪种情况,您都可以根据自己的喜好自定义 classes(在限制范围内 - 例如,class 必须是子 class - 直接或间接 - NSManagedObject).
- 正确。您可以在模型编辑器中添加、修改或删除属性。在
Category/Extension
的情况下,会自动进行相关的修改。在 Manual/None
的情况下,您可以手动更新扩展(或 class 文件),或者您可以重做 "create NSManagedObject subclass",这将使用修改后的属性详细信息更新扩展。如果不这样做,Xcode 将无法识别新的属性详细信息,也不会为它们提供代码完成(如果您尝试覆盖代码完成,也不会成功编译)。但与您认为的不同,这与标记为 @NSManaged
. 的属性无关
- 正确。在 class 定义(或扩展)中添加一个 @NSManaged 属性 足以告诉 Xcode 属性 存在(因此您可以在代码中引用它们)但不会创建相应的getter/setter。所以你的代码会崩溃。
- 是的,对于
Category/Extension
,只需根据需要创建和定制 class 文件。
- 是的,对于
Category/Extension
,属性在派生数据中自动创建的扩展文件中声明。
- 以任何方式更改 属性 定义 - 从 Date 到 NSDate,或将其标记为私有,或其他 - 只能在
Manual/None
情况下完成,因为派生数据中的扩展文件是每个新版本都会覆盖,因此所有更改都会丢失。
- 同上
- 同上
- 正确。如果您使用 KVC 访问属性,则无需创建单独的 NSManagedObject 子classes(自动或手动)即可编写您的应用程序。
关于你的最后一点:你不能随意改变属性定义的类型:在模型编辑器中指定的类型必须与属性定义中指定的类型相对应。您可以在相同类型的可选版本和非可选版本之间切换,您可以在 Date 和 NSDate 之间切换等,但是从 Date 切换到 String 将不起作用。我怀疑你是对的,这是由于 Swift 值类型和使用 as
的相应 Objective-C 引用类型之间的桥接。参见 here。
我读过
相同点是:
- 我可以随心所欲地自定义这两个 class。
- 我可以添加新属性或删除或重命名属性。即对于
category/extension
它将在新构建时更新(在派生数据中),并且在manual/none
的情况下它将保持 class 文件不变并更新文件导航中的扩展名即我不会以重复文件结束。这都是由 Xcode 处理的,因为它们标有预处理器@NSManaged
- 不允许将
@NSManaged public var name: String?
之类的内容直接转储到现有的NSManagedObject
子 class 中。我尝试执行entity.name = "John"
但出现以下错误:reason: '-[SomeEntity setName:]: unrecognized selector sent to instance 0x60400009b120'
。我相信这是合理的。我认为如果不使用核心数据模型编辑器,就不会创建 setter/getter 访问器方法。
区别是:
- 对于
Category/Extension
,您只需自己创建 class 并添加您需要的任何额外 functions/properties。 对于
Category/Extension
,属性是在派生数据中创建的,这就足够了。因为您永远不需要查看该文件。它的存在足以让事情正常进行。特别是在对您的 NSManaged 属性进行 更改 的上下文中:
正在更改 属性 类型,例如
NSDate
到Date
只允许Manual/None
。示例 here- 改变类型的可选性,例如
String?
到String
只允许Manual/None
。示例 here 更改 属性 访问级别,例如从
public
到private
只允许Manual/None
。示例 here话虽如此,但还是有显着差异 if 我选择
Manual/None
codegen 而 不选择 select 'create NSManagedObject subclass'。在这种情况下,我已经开始自己编写所有代码(来自 NSManagedObject 的 subclass 并为每个 属性 编写 NSManaged)...或者如果我不自己编写所有代码,那么我仍然可以 access/set 使用 KVC 的字段很尴尬!
简而言之,我只是想弄清楚使用 Manual/None
可以获得的全部功能。
问题: 除了我需要知道的 9 个 注释 之外,还有一个重要的 问题 将是:我如何将 NSDate
更改为 Date
或将可选更改为非可选而不破坏我的 NSManagedObject class 和我的对象图之间的映射NSDate
属性 到 String
确实中断了!!这是否与保证在 Swift 和 Objective-C 之间投射的东西有关,即可以通过 as
投射的东西——没有 ?
或 !
?
解决您的每条笔记并考虑代码生成设置为 Manual/None
和 Category/Extension
的情况:
- 是的,无论哪种情况,您都可以根据自己的喜好自定义 classes(在限制范围内 - 例如,class 必须是子 class - 直接或间接 - NSManagedObject).
- 正确。您可以在模型编辑器中添加、修改或删除属性。在
Category/Extension
的情况下,会自动进行相关的修改。在Manual/None
的情况下,您可以手动更新扩展(或 class 文件),或者您可以重做 "create NSManagedObject subclass",这将使用修改后的属性详细信息更新扩展。如果不这样做,Xcode 将无法识别新的属性详细信息,也不会为它们提供代码完成(如果您尝试覆盖代码完成,也不会成功编译)。但与您认为的不同,这与标记为@NSManaged
. 的属性无关
- 正确。在 class 定义(或扩展)中添加一个 @NSManaged 属性 足以告诉 Xcode 属性 存在(因此您可以在代码中引用它们)但不会创建相应的getter/setter。所以你的代码会崩溃。
- 是的,对于
Category/Extension
,只需根据需要创建和定制 class 文件。 - 是的,对于
Category/Extension
,属性在派生数据中自动创建的扩展文件中声明。 - 以任何方式更改 属性 定义 - 从 Date 到 NSDate,或将其标记为私有,或其他 - 只能在
Manual/None
情况下完成,因为派生数据中的扩展文件是每个新版本都会覆盖,因此所有更改都会丢失。 - 同上
- 同上
- 正确。如果您使用 KVC 访问属性,则无需创建单独的 NSManagedObject 子classes(自动或手动)即可编写您的应用程序。
关于你的最后一点:你不能随意改变属性定义的类型:在模型编辑器中指定的类型必须与属性定义中指定的类型相对应。您可以在相同类型的可选版本和非可选版本之间切换,您可以在 Date 和 NSDate 之间切换等,但是从 Date 切换到 String 将不起作用。我怀疑你是对的,这是由于 Swift 值类型和使用 as
的相应 Objective-C 引用类型之间的桥接。参见 here。