7

我有几个关于核心数据行为的“理论”问题,这些问题与一对多关系发生的情况以及何时依赖从父实体走关系以及何时应该构建新的获取请求有关。它们都非常相关。

背景

假设有一个父实体RPBook,它与 具有一对多关系RPChapter。一本书有很多章节。逆向也在核心数据模型中设置。涉及手动排序关系的基本形式,因此RPChapter实体具有chapterIndex属性。我在这里没有使用 iOS5 的新有序关系(也与这些问题无关)。

要访问书中的章节,可以使用chapters关系访问器:

RPBook *myBook; // Assume this is already set to an existing RPBook
NSSet *myChapters = myBook.chapters

使用/设置

在 iPhone 应用程序中,我们将从显示RPBook实例列表的表格视图开始。相应的章节不会作为支持 table view 的 fetched results controller 的 fetch 规范的一部分被预取,因为这些章节还不需要。

我现在选择其中一个RPBook实例,我被带到一个新页面,并且我RPBook的视图控制器中有这个实例引用,它没有chapters预取它。

filteredSetUsingPredicate:问题1:立即调用chapters关系

如果我想通过直接使用的chapters关系进行过滤filteredSetUsingPredicate:,考虑到我没有预先获取我正在查看RPChapter的当前的所有相关实例,它是否还能可靠地工作?RPBook换句话说,是否filteredSetUsingPredicate:会在该关系中的所有对象的幕后触发故障以执行其操作,或者它是否会误导性地仅根据哪些章节已经发生在内存中(如果有的话)给我结果?

如果我没有一本书的大量相关章节,我应该allObjects先调用它吗?IE

[[self.chapters allObjects] filteredArrayUsingPredicate:predicate]

而不仅仅是:

[self.chapters filteredSetUsingPredicate:predicate]

问题2:批量检索一本书的所有章节

如果我有一个RPBook实例,但没有与之相关的预取实例,我如何强制使用该关系RPChapter一次性获取一本书的所有章节?chapters这样做[myBook.chapters allObjects]还是我仍然可以从那个电话中得到故障?

根据上面的问题 1,我希望 Core Data 能够完成批次中的所有故障,而不是跳闸故障,RPChapter因为这会影响在关系上使用的filteredSetUsingPredicate:行为chapters

我必须诉诸明确的获取请求来执行此操作吗?我是否应该重新获取RPBook我已经拥有的,但这次,在获取请求中的请求,所有相关的章节也可以使用来获取setRelationshipKeyPathsForPrefetching:

最后一个选项对我来说似乎很浪费,b / c我已经有一个范围关系,从概念上表示RPChapter我感兴趣的所有实例的子集。尽可能地,我想只走对象图。

问题3:同一线程上RPChapter实例的NSFetchedResultsController

设置 在这种情况下,我有一个RPBook实例,但没有与之相关的预取RPChapter实例(但它们确实存在于 Store 中)。在同一个视图控制器中,我也有一个实例NSFetchedResultsController (FRC)RPChapter范围仅限于同一本书。所以这是同一个线程,同一个托管对象上下文。

RPChapterFRC 中的实例是否与我从中检索的实例对应的内存中的对象相同,RPChapter共享myBook.chapters相同ObjectID?换句话说,运行时是否曾经使用内存中的不同物理对象ObjectID从同一线程中的同一 MOC完成托管对象请求?

问题 4:NSFetchedResultsController在托管对象内部安装一个为关系查询提供服务的设计模式

chapters我正在尝试通过使用我的自定义托管对象子类中提供的内置关系来决定是否应该能够为内容经常更改的关系(在我的示例中的书中的章节)提供服务查询RPChapter,或者是否可以从设计/架构的角度来看,将一个FRC实例RPChapter安装到RPBook托管对象类上,以有效地为有关该书中章节的查询提供服务。

如果我可以仅依赖chapters访问器,这显然会更干净myBook,但是在存在大量目标实体的一对多关系的情况下,这里的 FRC 似乎实际上可能更具性能和效率。

这是矫枉过正还是合理使用 an以不同方式FRC查询 anRPBook的章节?不知何故,感觉就像我错过了简单地遍历对象图的机会。我希望能够相信当我加载我的实例时chapters关系总是最新的。RPBook

4

1 回答 1

10

问题 1

是的,它会起作用。当您调用[book chapters]该集合时,将自动填充。当您过滤这些对象时,它们会出错。

但是,您应该在NSFetchedResultsController此处使用谓词类似于 @"book == %@" 而不是抓取数组。

问题2

强制NSManagedObjectContext加载所有章节的最佳方法是执行 aNSFetchRequest并将其配置NSFetchRequest为返回完全实现的对象而不是错误。这将一次性预加载它们。但是,除非您拥有大量章节,否则您不会在这里节省很多钱。

为什么?

因为当您请求这些章节时,即使处于故障状态,Core Data 也会将数据加载到缓存中(不包括像二进制数据这样的一些边缘情况),因此当您“故障”一个对象时,它只是指针在其中移动内存和没有额外的磁盘命中。

您可能需要数千章才能看到预取的任何好处。

问题 3

是的。它们将是同一个对象。 NSManagedObject当从同一个NSManagedObjectContext. 这是该部门工作的一部分NSManagedObjectContext

问题 4

你想使用NSFetchedResultsControler它就是它的工作。手动管理这些东西是浪费的,而且几乎可以保证比 Core Data 的实现效率低。

但是,除非您从另一个线程对其进行调整,否则该关系始终是最新的。因此,如果您不期望更新,那么您可以只使用一个数组。我不会。

于 2012-02-16T21:37:56.147 回答