Objective c 生成的NSManagedObject子类+;CoreDataProperties.m文件实际上不是必需的吗?

Objective c 生成的NSManagedObject子类+;CoreDataProperties.m文件实际上不是必需的吗?,objective-c,xcode,core-data,Objective C,Xcode,Core Data,生成NSManagedObject子类时,xcode会创建两个额外的文件MyObject+CoreDataProperties.h&MyObject+CoreDataProperties.m,以使CoreData内容远离我们自己的代码 这很好,但我在一个WWDC剪辑中注意到,他们的示例中没有+CoreDataProperties.m文件。所以我试着在我的代码中删除它们,没有它们一切都可以编译和运行,它们似乎根本就没有必要 它们是我忽略的某种方式所必需的吗?如果不是,那么为什么xcode会生成它们

生成NSManagedObject子类时,xcode会创建两个额外的文件
MyObject+CoreDataProperties.h
&
MyObject+CoreDataProperties.m
,以使CoreData内容远离我们自己的代码

这很好,但我在一个WWDC剪辑中注意到,他们的示例中没有
+CoreDataProperties.m
文件。所以我试着在我的代码中删除它们,没有它们一切都可以编译和运行,它们似乎根本就没有必要

它们是我忽略的某种方式所必需的吗?如果不是,那么为什么xcode会生成它们呢?

简单回答:

不,没有必要

答案很长:

Objective-C是一种动态类型、后期绑定编程语言。简而言之,这意味着每个类型决策都可以在运行时而不是编译时做出,并且您可以访问对象的属性并向对象发送消息,而不知道对象的类型(类)

但核心数据框架和您作为核心数据和模型的用户不必知道实体类型的托管对象的类型。实体类型甚至不需要特定的类型。(我不经常生成类,如果生成,我会手动生成。)因此,与其他编程语言相比,这些生成的类不需要为编译器指定类型

但是,编译器希望至少查看每个方法一次,以获取签名(参数类型)。否则它会发出警告。甚至有可能有这样的工作代码

NSManagedObject *person = …
NSString *firstName = [person firstName];
…对于具有属性
firstName
的实体类型
Person
,编译器将警告您,他对方法
–firstName
一无所知

您可以键入如下内容:

NSManagedObject *person = …
NSString *firstName = [person valueForKey:@"firstName"];
(编译器知道
-valueForKey:
,因为这是在
NSObject
中声明的方法)

除此之外,您还可以获得代码完成、检查键入错误等好处。但是您不需要使用Xcode的代码生成工具。只需在接口的属性处声明这样一个类。可以使用
@dynamic
动态生成访问器。(就我个人而言,我几乎从不使用静态代码生成。)

编辑:在评论中添加讨论结果

因此,拥有该类别的接口(“.h-file”),编译器就有足够的知识来编译整个代码,而不会发出警告。如果保证(或在运行时检查)可以发送相应的消息,则这将在运行时起作用。这在许多情况下都是有意义的,从Objective-C开始,即。E用于转发和非正式协议。在核心数据上下文中,它用于动态生成标准访问器方法。没有任何实现,一切正常


然而,出于某些原因,人们希望实现。E价值变化的内务管理。在这种情况下,有一个可以编辑的存根实现非常有用。但对于标准行为来说,这是不必要的

如果要向类添加其他属性/实例变量,请使用单独的文件进行比较。
MyObject.*
就是为了这个,自动生成的
MyObject+CoreDataProperties.*
应该保持不变,以便在您更改模型时可以重新生成它们。但这来自
MyObject+CoreDataProperties.h
头文件,我指的是
MyObject+CoreDataProperties.m
文件。如果我删除.m文件,我不会得到编译器警告和所有正常的IDE代码完成,不需要使用
valueForKey
或类似的东西。只要我们谈论属性,这是正确的,因为编译器会看到访问器方法(没有警告),核心数据可以在运行时动态生成它们(没有rt问题)如前所述。但是,这样做类似于“棘手”,当您向类中添加其他方法或IVAR时,它会中断,因为它们不是动态创建的。其他方法和IVAR进入
MyObject.h
MyObject.m
,但不会中断。是的,如果您将其放在那里。但如果你把它放在这个类别中,它就不是了。即。您有一个计算属性。或者,由于某些原因(例如内部保管),您希望覆盖生成的属性之一。如前所述:只要您只将内容放入可由核心数据自动生成的界面中,它们就不是必需的。(基本上是访问内容)顺便说一句:未实现的类别在Objective-C中是一个非常非常古老的技巧,对核心数据来说并不特殊。也就是说,在过去(非正式)协议是这样宣布的。