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,不,这只是为了方便。即使您不更改类型,它也会起作用。 此处答案中引用的链接已失效。 @CyberMew 我认为它只会返回一个字典。然而,没有什么能阻止你使用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 和核心数据的主要内容,如果未能解决你的问题,请参考以下文章
swift中objective-NSDictionary(contentsOfFile)方法的替代方法[重复]