NSDictionary 和核心数据

Posted

技术标签:

【中文标题】NSDictionary 和核心数据【英文标题】:NSDictionary and Core Data 【发布时间】:2013-05-16 17:06:51 【问题描述】:

我正在尝试获取一些核心数据方面的知识。到目前为止,我已经掌握了创建实体以及从该实体添加、检索和删除值的窍门。

我的问题如下。使用核心数据时,将NSDictionary 属性存储在实体中的可能方式有哪些?

【问题讨论】:

我真的建议阅读一下 CoreData 的概念(查找 CoreData Programming Guide)。在大多数情况下 - NSDictionary 在某种程度上相当于内存中的实体 (NSManagedObject) - 两组键值对。因此,将 NSDictionary 存储为 NSManagedObject 的单个属性/属性的情况暗示了更高级别设计中的缺陷。 【参考方案1】:

你应该使用“可转换属性”:

    打开*.xcdatamodeld文件 选择实体 添加属性(例如命名为“info”)并将类型设置为“Transformable” 生成适当的NSManagedObject子类文件(文件->新建->文件...NSManagedObject子类) 打开 *.h 文件并将属性“info”的类型从 id 更改为 NSMutableDictionary*

其他一切都会自动运行

更多信息请见:https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html

【讨论】:

默认转换器序列化为 NSData。对于 NSDictionary,这是一个二进制 plist。 所以我每次重新生成 NSManagedObjects 时都需要将“.h”中的 id 更改为 NSDictionary?似乎有点痛苦,而且肯定是人们会忘记做的事情。 @lostintranslation,不,这只是为了方便。即使您不更改类型,它也会起作用。 此处答案中引用的链接已失效。 @Cyber​​Mew 我认为它只会返回一个字典。然而,没有什么能阻止你使用mutableCopy 来获取 NSMutableDictionary。即[info mutableCopy];【参考方案2】:

有几种方法可以解决这个问题:

一个。创建一个代表 NSDictionary 的实体,以便每个字典键都由一个实体属性表示。

b.如果您不喜欢上述创建单独实体的方法,您仍然可以将 NSDictionary 存储到 NSData 类型的单个核心数据字段中,前提是您先将 NSDictionary 序列化为 NSData。

//NSDictionary to NSData
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:dictionary forKey:@"Some Key Value"];
[archiver finishEncoding];
//  data is now ready to use

当您从 Core Data 读取 NSData 时,您还需要将其转换回 NSDictionary。

// NSData to NSDictionary
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSDictionary *dictionary = [[unarchiver decodeObjectForKey:@"Some Key Value"] retain];
[unarchiver finishDecoding];
//  dictionary is now ready to use

c。最后,您可以使用诸如 Sensible TableView 之类的持久性框架,您的所有数据结构都会在其中自动获取、显示和保存。为我自己节省了大量代码。

【讨论】:

如果您将属性定义为“可转换”,则会自动进行归档/取消归档。 谢谢大家,非常感谢您的回复。还有一件事,如果您希望将这些 NSDictionary 属性类型存储在核心数据中的字符串属性类型中呢? 这一切都可以自动完成,请参阅 Transformable Attributes 答案。将属性设置为 Transformable 就完成了。 我喜欢这个答案,即使它错过了最简单和最有能力的技术解决方案(使用可转换) - 因为它是唯一怀疑是否需要将 NSDictionary 存储在单个属性中的答案 - 而大多数情况下你希望一个实体用它的一组属性来反映一个 NSDictionary——所有这些都可以作为键值对使用,就像 NSDictionary 一样。【参考方案3】:

将属性类型更改为Transformable

如果您正在使用 mogenerator(您非常应该使用),则为可转换对象生成的默认类型是 id

要让 mogenerator 生成特定类型 NSDictionary,您可以为属性添加自定义键 attributeValueClassName,其值为 NSDictionary。参考这个screenshot。

【讨论】:

以上是关于NSDictionary 和核心数据的主要内容,如果未能解决你的问题,请参考以下文章

NSDictionary 和核心数据

swift中objective-NSDictionary(contentsOfFile)方法的替代方法[重复]

我无法从 plist 键值中解包值

核心数据架构问题 NSDictionary?

具有多个日期条目(每年大约 800 多个)的核心数据或 NSDictionary?啥是最容易实现的?

将 UIImage 转换为 NSData 并与核心数据一起保存