为啥会有一个子类 NSManagedObject?

Posted

技术标签:

【中文标题】为啥会有一个子类 NSManagedObject?【英文标题】:Why exactly would one subclass NSManagedObject?为什么会有一个子类 NSManagedObject? 【发布时间】:2011-10-30 20:02:00 【问题描述】:

我已经阅读了许多关于 NSManagedObject、Apple 文档等的 SO 问题,但我仍然不明白 NSManagedObject 的子类化是什么——它起到什么作用?

在 Apple 文档中,它谈到了我如何不能重写一堆方法、不应该使用自定义实例变量、等等等等(我还不明白其中的一些)等等 - 那又如何我可以使用 NSManagedObject 吗?有哪些限制、必须遵循的准则,哪些不是限制?

我正在尝试制作一个小盒子绘图程序来学习核心数据,并且我正在考虑将“绘图”方法添加到 NSManagedObject 的子类中,以便视图可以告诉他们自己绘制 - 这是允许吗?

所以,我一句话的问题是,子类化 NSManagedObject 和任何其他类之间的“真正”区别是什么——Core Data 用它做什么?

如果这太宽泛了,我会尽量缩小我的问题范围。

【问题讨论】:

【参考方案1】:

我仍然没有真正理解 NSManagedObject 的子类化是什么——它扮演什么角色?

为开发人员提供便利 - 在 CodeSense、更短的语法和一些有助于防止键拼写错误的编译时检查方面。

那么我可以用 NSManagedObject 做什么?有哪些限制、必须遵循的准则,哪些不是限制?

Xcode 中内置的 UI 将为您创建 NSManagedObject 子类 - 您真的不需要手动完成 - 但是,基本上,它们只是 NSManagedObjects 加上一些属性。而不是使用@synthesize 或类似的,你使用@dynamic 而Apple 会为你处理剩下的事情——将这些属性连接到getter/setter,它们模仿你通常使用“裸”NSManagedObject 所做的事情。

我正在尝试制作一个小盒子绘图程序来学习核心数据,并且我正在考虑将“绘图”方法添加到 NSManagedObject 的子类中,以便视图可以告诉他们自己绘制 - 这是允许吗?

你可以....但我不会。这听起来像是糟糕的设计 - 尝试将您的 ModelControllers 分开。

模型对象不应包含业务逻辑/绘图代码。将模型简单地用作应用程序的“状态”。让其他人负责绘图。另外,虽然我不能绝对权威地这么说,但我相信如果您正在处理从NSManagedObject 更新/检索信息,则会有一些开销。

基本上,这就像处理NSDictionary...排序。从字典中获取项目的效率低于访问ivar

对于执行绘图之类的应用程序 - 您可能希望通过为内存中的事物创建一个结构来避免这种开销,并且可能希望为持久性/序列化创建第二个类似的结构(如 CoreData)。

所以,我一句话的问题是,“真正”的区别是什么 在子类化 NSManagedObject 和任何其他类之间 - 什么 Core Data 用它做什么?

我会说 - 根本不要手动继承 NSManagedObject - 使用 Xcode 给你的东西。如果您想要更多(可能不是自定义构造函数),那么您可能找错了树。

编辑:

我认为当我说“根本不要手动继承 NSManagedObject”时,我的意思可能有些混乱

详细说明并合并其中一个响应:

从 Xcode 中的数据模型设计器开始,创建模型,然后使用以下菜单选项:

然后,您可以修改生成的类以包含自定义:

构造函数 数据转换方法 验证 格式化 排序描述符 过滤器

如果您的用例不适合该列表,您应该认真考虑将其放在其他地方(如您的示例中的“Draw”方法)。

上面提到的所有这些东西都可以附加到一个由 Xcode 为我们创建的 NSManagedObject 子类(我们没有“手动”创建)——它们都围绕着直接处理数据(格式/转换/etc)和/或围绕从核心数据中提取数据(过滤器/排序)。

他们不添加 iVar,不执行任何超出数据存储和检索范围的复杂操作。

【讨论】:

这个答案大部分都很好,但我不同意“根本不要手动子类 NSManagedObject”——我还没有一个最终没有子类 NSManagedObject 的核心数据项目。处理瞬态变量和数据转换是很常见的。它还提供了更好的类型安全性。在实践中,我几乎总是为每个实体创建一个子类,只是为了保持一致性。当有些是子类而有些不是时,它会变得混乱。 我将补充:(1) 自定义验证,(2) 工厂方法,(3) 字符串格式,(4) 关联排序描述符和过滤谓词的类方法。 @RobNapier - 哦,绝对 - 我所说的“手工”是指“如果你正在创建一个 Core Data 实体,并且你正在使用它在 Core Data 中存储东西,那么 Xcode 会/ 可以为您创建实体的开始 - 那么这是一个子类的合适位置” - 正如我所提到的,构造函数绝对是我可以看到添加的东西 - 数据转换方法以及你提到的都很好 - 但不要只是无缘无故地把本来是 NSObject 子类的所有东西都变成 NSManagedObject 子类(就像 OP 关于盒子的例子一样)。 @wkhatch - 我没有说业务逻辑应该放在你的UIViewControllers 中。典型场景是三层 - UI |业务逻辑 |数据访问。 @BenLings,对于任何事情(命名约定、设计模式等),人们都会有不同的看法。此外,适合示例应用程序的内容和适合实际应用程序的内容是两件不同的事情。在构建了几个类似于该示例程序的跨平台零售基于图形的应用程序之后,我表达了我的观点——仅此而已——我的观点。你可以不同意。但是,我认为该模型不是视图 - 并且不应该在其中内置渲染逻辑。这两种方法我都试过了,这对我来说效果最好。

以上是关于为啥会有一个子类 NSManagedObject?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 NSManagedObject 子类计算属性中使用关系? (核心数据,迅速)

为啥自动创建的 NSManagedObject 子类没有“正确”标题?

为啥我的类没有 NSManagedObject 属性时会出现错误?

子类化一个 NSManagedObject 子类

NSmanagedobject 的子类的子类

新的 NSManagedObject 子类与新的 NSObject 子类?