ios 在核心数据示例代码中存储 NSArray?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4546811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:23:43  来源:igfitidea点击:

Store NSArray In Core Data Sample Code?

core-dataiosnsarray

提问by Stunner

I have been searching for some sample code on how to store an NSArrayin Core Data for awhile now, but haven't had any luck. Would anyone mind pointing me to some tutorial or example, or better yet write a simple sample as an answer to this question? I have read thisbut it doesn't show an example of how to go about implementing a transformable attribute that is an NSArray. Thanks in advance!

我一直在寻找一些关于如何NSArray在 Core Data 中存储 a 的示例代码,但没有任何运气。有没有人介意给我指点一些教程或例子,或者更好地写一个简单的样本作为这个问题的答案?我已经阅读了这篇文章,但它没有展示如何实现一个可转换属性的示例,该属性是NSArray. 提前致谢!

回答by Resh32

If you really need to do it, then encode as data. I simply created a new filed called receiveas NSData (Binary data).

如果您确实需要这样做,则将其编码为数据。我只是创建了一个名为receiveNSData(二进制数据)的新文件。

Then in the NSManagedObject implementation:

然后在 NSManagedObject 实现中:

-(void)setReceiveList:(NSArray*)list{
     self.receive = [NSKeyedArchiver archivedDataWithRootObject:list];
}

-(NSArray*)getReceiveList{
    return [NSKeyedUnarchiver unarchiveObjectWithData:self.receive];
}

回答by quellish

Transformable attributes are the correct way to persist otherwise unsupported object values in Core Data (such as NSArray). From Core Data Programming Guide: Non-Standard Persistent Attributes:

可转换属性是在 Core Data(例如NSArray)中保留其他不受支持的对象值的正确方法。来自Core Data Programming Guide: Non-Standard Persistent Attributes

The idea behind transformable attributes is that you access an attribute as a non-standard type, but behind the scenes Core Data uses an instance of NSValueTransformer to convert the attribute to and from an instance of NSData. Core Data then stores the data instance to the persistent store.

可转换属性背后的想法是您将属性作为非标准类型访问,但在幕后 Core Data 使用 NSValueTransformer 的实例将属性与 NSData 的实例进行转换。然后 Core Data 将数据实例存储到持久存储中。

A transformable attribute uses an NSValueTransformer to store an otherwise unsupported object in the persistent store. This allows Core Data to store just about anything that can be represented as NSData - which can be very useful. Unfortunately, transformable attributes cannot be matched in a predicate or used in sorting results with the NSSQLiteStoreType. This means that transformable attributes are useful only for storage, not discovery of objects.

可转换属性使用 NSValueTransformer 在持久存储中存储其他不受支持的对象。这允许 Core Data 存储几乎任何可以表示为 NSData 的东西——这可能非常有用。不幸的是,可转换属性不能在谓词中匹配,也不能用于使用 NSSQLiteStoreType 对结果进行排序。这意味着可转换属性仅用于存储,而不用于对象的发现。

The default transformer allows any object that supports NSCoding(or NSSecureCoding) to be stored as a transformable attribute. This includes NSArray, UIColor, UIImage, NSURL, CLLocation, and many others. It's not recommended to use this for data that can be arbitrarily large, as that can have a significant performance impact when querying the store. Images, for example, are a poor fit for transformable attributes - they are large bags of bytes that fragment the store. In that case, it's better to use the external records storage capabilities of Core Data, or to store the data separately as a file, and store the URL to the file in Core Data. If you must store a UIImagein Core Data, be sure you know the trade offs involved.

默认转换器允许将支持NSCoding(或NSSecureCoding) 的任何对象存储为可转换属性。这包括NSArrayUIColorUIImageNSURLCLLocation,和其他许多人。不建议将此用于可以任意大的数据,因为这会在查询存储时对性能产生重大影响。例如,图像不适合可转换属性——它们是大包的字节,碎片化存储。在这种情况下,最好使用 Core Data 的外部记录存储功能,或者将数据单独存储为文件,并将文件的 URL 存储在 Core Data 中。如果您必须将 a 存储UIImage在 Core Data 中,请确保您知道所涉及的权衡。

Creating a transformable attribute is easy:

创建一个可转换的属性很容易:

? In the Xcode Core Data Model Editor, select the model attribute you want to modify. In the right side inspector, set the attribute type as "Transformable". You can leave the "Name" field blank to use the default transformer. If you were using a custom transformer, you would enter the class name here and register the class using +[NSValueTransformer setValueTransformer:forName:]somewhere in your code.

? 在 Xcode Core Data Model Editor 中,选择要修改的模型属性。在右侧检查器中,将属性类型设置为“可转换”。您可以将“名称”字段留空以使用默认转换器。如果您使用的是自定义转换器,您将在此处输入类名并使用+[NSValueTransformer setValueTransformer:forName:]代码中的某处注册该类。

Core Data Model Editor Transformable Attribute

核心数据模型编辑器可转换属性

? In your NSManagedObjectsubclass header declare the property that describes the transformable attribute with the correct type. In this case, we're using NSArray:

? 在您的NSManagedObject子类标头中声明描述具有正确类型的可转换属性的属性。在这种情况下,我们使用NSArray

@property (nonatomic, retain) NSArray *transformedArray;

@property (nonatomic, retain) NSArray *transformedArray;

? In the NSManagedObjectsubclass implementation file the property should be dynamic:

? 在NSManagedObject子类实现文件中,属性应该是动态的:

@dynamic transformedArray;

@dynamic transformedArray;

And you are done. When an NSArrayvalue object is passed to setTransformedArray:that array is retained by the object. When the context is saved Core Data will transform the NSArrayinto NSDatausing the NSValueTransformerdescribed in the model. The NSDatabytes will be saved in the persistent store.

你已经完成了。当一个NSArray值对象传递给setTransformedArray:该数组时,该对象会保留该对象。当上下文被保存时,Core Data 将使用模型中的描述转换NSArray成。该字节将被保存在持久性存储。NSDataNSValueTransformerNSData

回答by Philip Regan

You don't store an NSArraynatively in Core Data. You need to transform the values stored withinthe array into something Core Data can use, and then save the data in the store so that you can push and pull it to your NSArrayas needed.

您不会NSArray在 Core Data 中本地存储一个。您需要将存储数组中的值转换为 Core Data 可以使用的值,然后将数据保存在 store 中,以便您可以NSArray根据需要将其推送和拉取。

回答by Helge Becker

Philip's answer is right. You don't store arrays in Core Data. It is totally against what Core Data is made for. Most of the time you don't need the information of the array but one and that one can get dynamically loaded by Core Data. In the case of collections, it makes no difference if you iterate through an array of your whatever properties or of an array of fetched results on an NSSet(which is basically just an array too).

菲利普的回答是正确的。您不在核心数据中存储数组。这完全违背了 Core Data 的用途。大多数情况下,您不需要数组的信息,而是需要一个可以由 Core Data 动态加载的信息。在集合的情况下,如果您遍历一个包含任何属性的数组或一个在 an 上获取的结果数组NSSet(基本上也只是一个数组),则没有任何区别。

Here is the explanation what Philip said. You can't store an array directly, but you can create a property list from it. There is a method in all NS Arraytypes that gives you a nice and clean string and core data love strings. The cool thing about property lists stored as strings is, they can become what they were. There is a method for that in NSString. Tataaa...

这是菲利普所说的解释。您不能直接存储数组,但可以从中创建属性列表。所有 NS Arraytypes 中都有一个方法可以为您提供漂亮干净的字符串和核心数据爱字符串。以字符串形式存储的属性列表很酷的一点是,它们可以变成原来的样子。中有一种方法可以做到这一点NSString。塔塔阿...

There is a price of course. Arrays as property lists can get gigantic and that doesn't go well with iOS devices where RAM is limited. Trying to save an array to core data indicates a poor entity design especially for large data. A small array is OK for speed reasons.

当然是有代价的。作为属性列表的数组可能会变得非常庞大,这对于 RAM 有限的 iOS 设备来说并不合适。尝试将数组保存到核心数据表明实体设计不佳,尤其是对于大数据。出于速度原因,小阵列是可以的。

Another, less space consuming way, is to use binary property lists. Those come close to zip sizes when stored in Core Data or directly in the filesystem. Downside is, you can't simply open and read them like an XML or JSON file. For development I prefer something human readable and for release the binary version. A constant tied to the DEBUGvalue in the preprocessor takes care of that, so I don't have to change my code.

另一种占用空间较少的方法是使用二进制属性列表。当存储在 Core Data 中或直接存储在文件系统中时,它们接近 zip 大小。缺点是,您不能像 XML 或 JSON 文件一样简单地打开和读取它们。对于开发,我更喜欢人类可读的东西并发布二进制版本。一个与DEBUG预处理器中的值相关的常量负责处理这个问题,所以我不必更改我的代码。

回答by Caleb

Core Data stores instances of NSManagedObject or subclasses of same. NSManagedObject itself is very much like a dictionary. To-many relationships between objects are represented as sets. Core Data has no ordered list that would correspond to an array. Instead, when you retrieve objects from a Core Data store, you use a fetch request. That fetch request can specify one or more sort descriptors that are used to sort the objects, and the objects returned by a fetch request are stored in an array.

核心数据存储 NSManagedObject 的实例或其子类。NSManagedObject 本身非常像一本字典。对象之间的多对多关系表示为集合。Core Data 没有对应于数组的有序列表。相反,当您从 Core Data 存储中检索对象时,您使用的是 fetch 请求。该提取请求可以指定一个或多个用于对对象进行排序的排序描述符,并且提取请求返回的对象存储在一个数组中。

If preserving the order of objects is important, you'll need to include an attribute in your entity that can be used to sort the objects when you fetch them.

如果保留对象的顺序很重要,则需要在实体中包含一个属性,该属性可用于在获取对象时对对象进行排序。