Core Data实体继承 --> 有哪些限制?

11

我想把这个问题发布到社区上。我正在使用CoreData,并且有两个实体。这两个实体都有一个分层关系。我现在注意到很多功能是重复的,所以我在思考是否应该重新构建一个基础实体(抽象的HierarchicalObject),并让我的实体继承它们。

问题是,这种继承有哪些限制需要考虑?阅读一些帖子后,我看到了一些权衡,如果我的假设是正确的,请告诉我。

  1. (好处) 整理结构,在一个地方保留HierarchicalObject的功能。
  2. (可以接受) 使用继承,两个对象现在会出现在同一个sqlite表中(我正在使用Sqlite作为后端)。如果对象数量增长,搜索/排序可能需要更长时间?不确定这是否是一个巨大的问题,因为在我的情况下,对象数量应该相当静态。
  3. (不太好) 通过继承,关系可能变得更加复杂? (http://www.cocoadev.com/index.pl?CoreDataInheritanceIssues)

还有其他需要考虑的事情吗?

谢谢你的评论。

3个回答

17

我认为在实体和类之间划等号是一个错误。尽管它们非常相似,但它们确实有一些重要的区别。

最重要的区别在于,实体没有代码,就像类一样。因此,当您拥有具有重复属性的实体时,您不会添加太多额外的编码和可能引入错误的风险。

许多人认为类继承必须与实体继承平行。事实并非如此。只要一个类从NSManagedObject派生并响应代表实体的正确键值消息,该类可以在继承方面有许多愉快的冒险,并不反映在实体的继承中。例如,通常会创建一个自定义基类,紧挨着NSManagedObject,然后所有后续的受管理对象子类都从那个基类继承,而不管它们的实体是什么。

我认为唯一需要绝对需要实体继承的时候是当您需要不同的实体出现在同一关系中时。例如:

Owner{
  vehical<-->Vehical.owner
}

Vehical(abstract){
  owner<-->Owner.vehical
}

Motocycle:Vehical{ 

}

Car:Vehical{

}

现在 Owner.vehical 可以容纳一个 Motocycle 对象或一个 Car 对象。注意,MotocycleCar 的托管对象类继承不必相同。例如,你可以有这样的继承关系:Motocycle:TwoWheeled:NSManagedObjectCar:FourWheeled:NSManagedObject,一切都将正常工作。

最终,实体只是给上下文提供指示,告诉它对象图如何组合在一起。只要您的实体安排能够实现这一点,您在设计细节方面就有很大的灵活性,比类的情况更加灵活。


1
感谢您的详细解释!在我的情况下,这些实体并不是真正相关的实体,更多是为了代码“清理”和保持模型的健康。但考虑到您的评论和 Kendall 的建议,我打算将其保留原样。代码量不是很大,也不想处理潜在的负面影响。再次感谢! - Yenyi

14

我认为提到iOS 10上的Notes应用程序在其Core Data模型中使用继承是有用的。它们使用一个基础实体SyncingObject,其中包括Note和Folder等7个子实体。正如你所提到的,所有这些都存储在相同的SQLite表中,该表有106列,由于在所有实体之间共享,因此大多数都为NULL。他们还将文件夹-笔记的一对多关系实现为多对多,从而创建了一个数据透视表,这可能是解决继承问题的一种方法。

使用实体继承有几个优点,这些优点很可能超过了存储限制。例如,唯一约束可以跨实体唯一。父实体的获取请求可以返回多个子实体,使使用获取结果控制器的UI更简单,例如在侧边栏中按账户或文件夹分组。Notes使用此功能显示“所有笔记”行,该行实际上是Account子实体。


1
你有这方面的资料吗?我很想了解更多。 - hidden-username
2
抱歉,我没有,这只是我的逆向工程。我使用momdec来反编译模型和Hopper来反编译代码。 - malhal

2

过去,我曾经在具有继承的模型数据迁移方面遇到问题 - 你可能需要尝试一下,看看是否可以让它正常工作。

正如你所指出的,所有对象都放在一个表中。

然而,由于Core Data正在管理一个对象图,因此最好保持结构的自然方式来建模对象,包括继承。保持模型合理化非常重要,这样您就可以减少维护代码的工作量。

我个人在自己的应用程序中使用了一个相当复杂的CD模型,其中包含继承,效果还不错(除了我之前提到的数据迁移问题,但是那对我来说总体上都很棘手,我不再依赖它工作)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接