4

在有关在后台工作的 CoreData Apple Docs 中,我遇到了以下建议:

例如,您可以将获取请求配置为仅返回对象 ID ,但还包括行数据(并更新行缓存) ——如果您只是要将这些对象 ID 从后台线程传递到另一个线程,这将很有用.

我想知道你如何实现这个获取请求?具体如何更新行缓存。

认为这就是获取 ID 的方法:

NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"MyItem"]; // iOS 5 method
request.returnsObjectsAsFaults = YES; 

我该怎么做?

4

2 回答 2

16

默认情况下,includesPropertyValues 为 YES,returnsObjectsAsFaults 也为 YES。

如果您只想返回对象 ID,则需要使用...

fetchRequest.resultType = NSManagedObjectIDResultType;

但是,没有要获取的属性,并且不会填充行缓存。你只会得到一堆对象 ID。

请注意,BY DEFAULT (resultType == NSManagedObjectResultType),因为 includesPropertyValues 和 returnObjectsAsFaults 都是 YES,所以 fetch 将返回对象作为错误(对象 ID 是可访问的),并且行缓存将被填充 - 但数据不会真正是“在内存中”,因为对象仍然是一个错误......但你仍然可以得到它的对象 ID。

然后,您需要做的就是向对象询问其 objectID。

我想,所有这一切都可以说你所要求的行为是你默认得到的。那么,您是否有问题,或者有什么原因您认为您没有得到这种行为?

编辑

嗯...我是说默认情况下,你得到了你想要的。如果您只是填写一个获取请求,并且不更改任何属性,returnObjectsAsFaults 为 YES - 因此返回给您的对象将是错误的。此外,includesPropertyValues 也是 YES - 因此行缓存中将提供一些属性数据。

您可以通过调用 managedObject.objectID 来访问 objectID 属性。

编辑

我很抱歉,因为我显然没有做好沟通工作,因为这将是我第三次说了同样的话。

创建 NSFetchRequest 时,它有几个默认设置的属性。

resultType 默认设置为 NSManagedObjectResultType。这意味着,除非您更改它,否则它仍然是 NSManagedObjectResultType。这也意味着您从 fetch 中获得的结果数组将包含一个 NSManagedObjects 数组(而不是返回一个计数、字典或 ObjectID)。

默认情况下,returnObjectsAsFaults 设置为 YES。这意味着,除非您更改它,否则它仍然是 YES。这也意味着从 fetch 返回的对象将是错误的。NSManagedObject 不会用属性数据来实现。该对象将是一个错误。它将有足够的元数据来了解其类型、对象 ID 和其他一些内容。

includesPropertyValues 默认设置为 YES。这意味着,除非您更改它,否则它仍然是 YES。这也意味着一些属性数据将被提取到行缓存中。

从 fetch 返回的每个 NSManagedObject 将:

  1. 有一个对象 ID
  2. 是一个错误,所以数据实际上并没有完全加载到内存中
  3. 一些属性数据将在行缓存中

这就是你所要求的一切。我不确定我还能添加什么(不再重复自己)。

另外,请注意,如果您只需要对象 ID,您可以将 resultType 设置为 NSManagedObjectIDResultType。

直接来自 NSFetchRequest 文档...

包括属性值

您可以将 includesPropertyValues 设置为 NO 以通过避免创建对象来表示属性值来减少内存开销。但是,您通常应该这样做,但是,如果您确定您不需要实际的属性数据或者您已经在行缓存中拥有信息,否则您将多次访问数据库。

在正常获取期间(includesPropertyValues 为 YES),Core Data 获取匹配记录的对象 ID 和属性数据,用信息填充行缓存,并将托管对象作为故障返回(请参阅returnsObjectsAsFaults)。这些故障是托管对象,但在触发故障之前,它们的所有属性数据仍驻留在行缓存中。当故障被触发时,Core Data 从行缓存中检索数据——无需返回数据库。

如果 includesPropertyValues 为 NO,那么 Core Data 只获取匹配记录的对象 ID 信息——它不会填充行缓存。Core Data 仍然返回托管对象,因为它只需要托管对象 ID 来创建故障。但是,如果您随后触发该故障,Core Data 会在(空)行缓存中查找,没有找到任何数据,然后再次返回存储区获取数据。

和...

返回ObjectsAsFaults

默认值为是。如果结果类型(参见 resultType)是 NSManagedObjectIDResultType,则不使用此设置,因为对象 ID 没有属性值。如果您知道需要从返回的对象访问属性值,则可以将 returnObjectsAsFaults 设置为 NO 以获得性能优势。

默认情况下,当您执行 fetch 时,returnObjectsAsFaults 为 YES;Core Data 获取匹配记录的对象数据,用信息填充行缓存,并返回托管对象作为故障。这些故障是托管对象,但在触发故障之前,它们的所有属性数据都驻留在行缓存中。当故障被触发时,Core Data 从行缓存中检索数据。尽管此操作的开销很小,但对于大型数据集,它可能变得不简单。如果您需要从返回的对象中访问属性值(例如,如果您遍历所有对象以计算特定属性的平均值),那么将 returnObjectsAsFaults 设置为 NO 以避免额外的开销会更有效。

于 2012-05-10T13:26:09.763 回答
8

让我用简单的方法解释一下

默认情况下,NSFetchRequest

resultType: NSManagedObjectResultType

returnsObjectsAsFaults: YES

includesPropertyValues: YES

这里返回的对象(在内存中)只有objectID属性,其他所有属性都是空的(这就是所谓的故障

包括属性值

YES:表示对象属性在行缓存中(CoreData的一些特殊缓存),所以当你访问这些属性时,CoreData会在行缓存中查找它们

NO:表示没有行缓存,当您访问这些属性时,CoreData 将再次查询 SQLite

返回ObjectsAsFaults

YES:允许 includesPropertyValues 生效(意味着允许出现故障

NO:返回对象,其所有属性都在内存中

注意:有两种故障:托管对象故障关系故障

在这里阅读更多错误限制了对象图的大小

所以在你的情况下,只需使用默认值

于 2014-04-11T08:17:18.530 回答