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

Run*_*oop 175 core-data objective-c nsdictionary nsarray ios

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

Bar*_*ark 245

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

另一种方法是使用Core Data to-many关系来模拟数组或字典集合的语义.数组更容易,所以让我们开始吧.核心数据对多关系是真正建模一套,所以如果你需要数组一样的功能,你必须要么排序集(使用已取得的财产是一种方便的方式来做到这一点),或添加额外的索引属性的实体存储数组项并自己管理索引.如果要存储同构数组(所有条目都是相同类型),则可以轻松地为数组实体建模实体描述.如果没有,您将必须决定是否使用可转换属性来存储项目数据或创建项目实体系列.

对字典建模可能需要与存储密钥和值的一组实体的多对多关系.键和值都类似于上面描述的数组的项实体.因此,它们可以是本机类型(如果您提前了解它们),可转换属性或与特定类型实体系列中的实例的关系.

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

对于结构化数据,例如地址,花费时间明确地对实体建模(例如,地址的每个部分的属性)几乎总是更容易.除了避免所有额外的代码来建模字典,这使得您的UI更容易(绑定将"正常工作")和您的验证逻辑等更清晰,因为其中大部分可以由Core Data处理.

更新

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

  • @pixelfreak可变形的使用取决于*如何*你需要使用集合中的项目.如果您需要查询它们,或者您希望能够懒惰地加载它们中的一些或全部,则可转换属性将不起作用.如果你不需要延迟加载,不需要查询并且总是需要*all*of items或none,可转换属性可能适合你(并且当然很容易实现). (3认同)
  • Barry所说的更详细地描述了核心数据编程指南,[非标准持久属性]一章(http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes. HTML#// apple_ref/DOC/UID/TP40001919-SW1). (3认同)
  • 关于有序集合的注意事项:不要将它们用于多方面的关系,多方面有超过几千个对象.如果这样做,保存可能会开始花费很长时间以阻止线程. (2认同)
  • 我不明白"新订单".这是属性吗?因为我无法在属性类型菜单中看到它. (2认同)

cal*_*leb 11

我有类似的问题.就我而言,我想映射一个字符串数组.我遵循了巴里的建议,最终让它发挥作用.以下是一些代码的样子(希望能为其他遇到此问题的人澄清事情)......

我的实体看起来像这样:

@interface AppointmentSearchResponse : NSManagedObject
@property (nonatomic, retain) NSSet *messages;
@end
Run Code Online (Sandbox Code Playgroud)

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

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];
Run Code Online (Sandbox Code Playgroud)

所以这里的关键项目是:

  • 我正在使用NSSet作为属性类型
  • 我使用NSTransformableAttributeType作为核心数据管理对象模型中的属性类型.