最佳实践? - 数组/字典作为核心数据实体属性 [关闭]

Posted

技术标签:

【中文标题】最佳实践? - 数组/字典作为核心数据实体属性 [关闭]【英文标题】:Best practice? - Array/Dictionary as a Core Data Entity Attribute [closed] 【发布时间】:2009-10-13 20:16:25 【问题描述】:

我是 Core Data 的新手。我注意到集合类型不能用作属性类型,并且想知道将数组/字典类型数据存储为属性的最有效方法是什么(例如,构成街道、城市等地址的元素确实如此不需要单独的实体,并且比单独的属性/字段更方便地存储为字典/数组)。谢谢。

【问题讨论】:

为地址创建一个带有字符串字段的实体可能比你必须记住你的键的字典更容易使用...... 【参考方案1】:

Core Data 中没有“本机”数组或字典类型。您可以将NSArrayNSDictionary 存储为可转换属性。这将使用NSCoding 将数组或字典序列化为NSData 属性(并在访问时适当地反序列化它)。这种方法的优点是简单。缺点是您无法查询数组或字典(它在数据存储中存储为 BLOB),如果集合很大,您可能必须将大量数据移入/移出数据存储(如果它是SQLite 数据存储)只是为了读取或修改集合的一小部分。

另一种方法是使用 Core Data 对多关系来建模数组或字典集合的语义。数组更容易,所以让我们从它开始。 Core Data to-many 关系实际上是在对集合进行建模,因此如果您需要类似数组的功能,则必须对集合进行排序(使用获取的属性是一种方便的方法)或向实体添加额外的索引属性存储数组项并自己管理索引。如果您要存储同构数组(所有条目都是同一类型),则很容易为数组实体建模实体描述。如果不是,您必须决定是使用可转换属性来存储商品数据还是创建一系列商品实体。

对字典进行建模可能需要与一组存储键和值的实体建立一对多关系。键和值都类似于上面描述的数组的项目实体。因此它们可以是原生类型(如果您提前知道的话)、可转换的属性或与特定类型实体系列中的实例的关系。

如果这一切听起来有点令人生畏,那就是。将任意数据硬塞到像 Core Data 这样依赖于模式的框架中是很困难的。

对于结构化数据,例如地址,花时间对实体进行显式建模几乎总是更容易(例如地址的每个部分的属性)。除了避免为字典建模的所有额外代码之外,这还使您的 UI 更容易(绑定将“正常工作”)并且您的验证逻辑等更加清晰,因为其中大部分都可以由 Core Data 处理。

更新

从 OS X 10.7 开始,Core Data 包含一个有序集合类型,可以用来代替数组。如果您可以针对 10.7 或更高版本,这是有序(类数组)集合的最佳解决方案。

【讨论】:

第二 - 确认了我已经想到的但我不知道可转换属性。 @pixelfreak 使用可变形取决于如何您需要使用集合中的项目。如果您需要查询它们,或者您希望能够延迟加载其中的部分或全部,则可转换属性将不起作用。如果您不需要延迟加载,不需要查询并且总是需要所有项或没有,那么可转换属性可能对您有用(并且当然很容易实现)。 《核心数据编程指南》Non-Standard Persistent Attributes 章节中更详细地描述了 Barry 所说的内容。 关于有序集合的注意事项:不要将它们用于多方上超过几千个对象的多对多关系。如果这样做,保存可能会开始花费很长时间以致阻塞线程。 我不了解“新有序集”。它是一个属性吗?因为我在属性类型菜单中看不到。【参考方案2】:

我遇到了类似的问题。就我而言,我想映射一个字符串数组。我听从了巴里的建议,终于成功了。下面是一些代码的样子(希望可以为遇到此问题的其他人澄清事情)...

我的实体看起来像这样:

@interface AppointmentSearchResponse : NSManagedObject
@property (nonatomic, retain) NSSet *messages;
@end

我的管理对象模型代码(核心数据)代码如下所示:

NSEntityDescription *entityDescription = [[NSEntityDescription alloc] init];
[entityDescription setName:@"AppointmentSearchResponse"];
[entityDescription setManagedObjectClassName:@"AppointmentSearchResponse"];

NSMutableArray *appointmentSearchResponseProperties = [NSMutableArray array];
NSAttributeDescription *messageType = [[NSAttributeDescription alloc] init];    
[messageType setName:@"messages"];
[messageType setAttributeType:NSTransformableAttributeType];
[appointmentSearchResponseProperties addObject:messageType];

[entityDescription setProperties:appointmentSearchResponseProperties];

所以这里的关键是:

我正在为属性类型使用 NSSet 我在核心数据托管对象模型中使用 NSTransformableAttributeType 作为属性类型。

【讨论】:

那么您是否会将这段代码放在 AppointmentSearchResponse.m 的 init 方法中?

以上是关于最佳实践? - 数组/字典作为核心数据实体属性 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

基于实体属性确保 CoreData 实体唯一的最佳实践

保管 EAV 的最佳实践

核心数据:获取关系属性

核心数据模型对象保存的最佳实践

fetchedResultsController 获取带有谓词的实体的最佳实践

预加载具有多对多关系的核心数据的最佳实践