我一直在寻找一些关于如何在核心数据中存储NSArray
一段时间的示例代码,但是没有任何运气。有人会介意给我一些教程或例子,或者更好的是写一个简单的样本作为这个问题的答案吗?我已阅读this但未显示如何实施NSArray
的可转换属性的示例。提前谢谢!
答案 0 :(得分:37)
如果你真的需要这样做,那么编码为数据。我只是创建了一个名为receive
的新文件作为NSData(二进制数据)。
然后在NSManagedObject实现中:
-(void)setReceiveList:(NSArray*)list{
self.receive = [NSKeyedArchiver archivedDataWithRootObject:list];
}
-(NSArray*)getReceiveList{
return [NSKeyedUnarchiver unarchiveObjectWithData:self.receive];
}
答案 1 :(得分:29)
可转换属性是在Core Data中保留其他不受支持的对象值的正确方法(例如NSArray
)。来自Core Data Programming Guide: Non-Standard Persistent Attributes:
可转换属性背后的想法是您将属性作为非标准类型访问,但在幕后,Core Data使用NSValueTransformer的实例将属性转换为NSData实例和从NSData实例转换属性。然后,Core Data将数据实例存储到持久存储中。
可转换属性使用NSValueTransformer在持久性存储中存储否则不受支持的对象。这允许Core Data存储几乎任何可以表示为NSData的东西 - 这可能非常有用。遗憾的是,转换属性不能在谓词中匹配,也不能用于使用NSSQLiteStoreType对结果进行排序。这意味着可转换属性仅对存储有用,而不是对象的发现。
默认转换器允许将支持NSCoding
(或NSSecureCoding
)的任何对象存储为可转换属性。其中包括NSArray
,UIColor
,UIImage
,NSURL
,CLLocation
以及其他许多内容。不建议将此用于可能任意大的数据,因为在查询商店时会对性能产生重大影响。例如,图像不适合可转换的属性 - 它们是大块的字节,可以分割商店。在这种情况下,最好使用Core Data的外部记录存储功能,或者将数据作为文件单独存储,并将URL存储在Core Data中的文件中。如果您必须在核心数据中存储UIImage
,请确保您知道所涉及的权衡。
创建可转换属性很简单:
•在Xcode Core Data Model Editor中,选择要修改的模型属性。在右侧检查器中,将属性类型设置为" Transformable"。你可以留下"姓名"字段为空以使用默认变换器。如果您使用自定义转换器,则应在此处输入类名,并在代码中的某处使用+[NSValueTransformer setValueTransformer:forName:]
注册该类。
•在NSManagedObject
子类标题中,声明描述具有正确类型的可转换属性的属性。在这种情况下,我们正在使用NSArray
:
@property (nonatomic, retain) NSArray *transformedArray;
•在NSManagedObject
子类实现文件中,属性应该是动态的:
@dynamic transformedArray;
你完成了。将NSArray
值对象传递给setTransformedArray:
时,该对象保留该数组。保存上下文后,Core Data会使用模型中描述的NSArray
将NSData
转换为NSValueTransformer
。 NSData
个字节将保存在持久存储中。
答案 2 :(得分:26)
您不会在核心数据中本地存储NSArray
。您需要将在数组中存储的值转换为Core Data可以使用的值,然后将数据保存在商店中,以便您可以根据需要将其推送到NSArray
。
答案 3 :(得分:8)
菲利普的回答是正确的。您不在Core Data中存储数组。这完全违背了Core Data的用途。大多数情况下,您不需要数组的信息,但是一个可以由Core Data动态加载。对于集合,如果在NSSet
(基本上只是一个数组)上遍历任何属性或获取结果数组的数组,则没有区别。
以下是菲利普所说的解释。您不能直接存储数组,但可以从中创建属性列表。所有NS Arraytypes中都有一个方法可以为您提供一个漂亮而干净的字符串和核心数据。存储为字符串的属性列表很酷,它们可以变成它们的样子。在NSString
中有一种方法。 TATAAA ...
当然有代价。 作为属性列表的数组可能会变得很大,而且对于RAM有限的iOS设备而言,这种情况并不顺利。尝试将数组保存到核心数据表明实体设计较差,特别是对于大数据。出于速度原因,一个小阵列是可以的。
另一种占用空间较少的方法是使用二进制属性列表。当存储在Core Data中或直接存储在文件系统中时,它们接近于zip大小。缺点是,您不能像XML或JSON文件那样简单地打开和读取它们。对于开发,我更喜欢人类可读的东西并发布二进制版本。与预处理器中的DEBUG
值相关联的常量负责处理,因此我不必更改代码。
答案 4 :(得分:1)
Core Data存储NSManagedObject的实例或其子类。 NSManagedObject本身就像一本字典。对象之间的多对多关系表示为集合。核心数据没有与数组对应的有序列表。相反,当您从Core Data存储中检索对象时,您将使用获取请求。该获取请求可以指定一个或多个用于对对象进行排序的排序描述符,并且由获取请求返回的对象存储在数组中。
如果保留对象的顺序很重要,则需要在实体中包含一个属性,可以在获取对象时对其进行排序。