核心数据故障和多对多关系的获取

时间:2012-02-16 20:20:56

标签: core-data ios5 relationship fault prefetch

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

背景

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

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

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

用法/设置

在iPhone应用程序中,我们首先会看到一个显示RPBook个实例列表的表格视图。相应的章节不会作为提取结果控制器支持表视图的提取规范的一部分预先提取,因为这些章节尚不需要。

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

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

如果我想直接使用chapters通过filteredSetUsingPredicate:关系进行过滤,那么即使我没有预先获取当前所有相关的RPChapter实例RPBook我在看?换句话说,filteredSetUsingPredicate:是否会在该关系中的所有对象的幕后触发错误以执行其操作,或者它会误导性地仅根据已经碰巧在内存中的哪些章节给出结果(如果任何)?

如果我的书中没有相关数量的相关章节,那么我应该首先调用allObjects来设置这个样式吗?即

[[self.chapters allObjects] filteredArrayUsingPredicate:predicate]

而不只是:

[self.chapters filteredSetUsingPredicate:predicate]

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

如果我有一个RPBook实例,但没有与之相关的预取RPChapter个实例,我如何使用{{{} {{} {{}} 1}}关系? chapters是否会这样做,或者我仍然可以从该呼叫中恢复故障?

我希望Core Data能够完成批处理中的所有错误,而不是针对奇怪[myBook.chapters allObjects]所引发的错误,如果这会影响在RPChapter关系上使用filteredSetUsingPredicate:的行为,根据上述问题1。

我是否必须使用显式提取请求来执行此操作?我应该重新获取我已经拥有的chapters,但是这次请求获取请求,还是使用RPBook获取所有相关章节?

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

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

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

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

问题4:在托管对象中安装ObjectID以提供关系查询的设计模式

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

如果我可以依赖RPChapter实例中的RPBook访问器,那显然更清晰,但是在这里有大量目标实体的情况下,这里的FRC似乎可能更具性能和效率。存在多对多的关系。

这是否过度使用,或者chapters是否可以合理地使用myBook以不同方式查询FRC章节?不知怎的,感觉我错过了简单地走对象图的机会。我希望能够信任,当我加载RPBook实例时,chapters关系始终是最新的。

1 个答案:

答案 0 :(得分:10)

问题1

是的,它会起作用。当您致电[book chapters]时,该设置将自动填充。当您对这些对象进行过滤时,它们将会出错。

但是,你应该使用NSFetchedResultsController这里的谓词类似@“book ==%@”而不是抓住数组。

问题2

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

为什么?

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

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

问题3

是。它们将是同一个对象。从同一NSManagedObject检索时,将始终共享NSManagedObjectContext个实例。这是NSManagedObjectContext

工作的一部分

问题4

您想使用NSFetchedResultsControler作为其工作。手动管理这些东西是浪费的,几乎可以保证效率低于Core Data的实现。

然而,除非您从另一个线程调整它,否则 的关系始终是最新的。因此,如果您不希望更新,那么您可以使用数组。我不愿意。