2012-07-21 43 views
2

我有一个非常简单的小模式,它看起来像这样:一批核心断裂作用亲子关系数据

特雷尔 - >段 - >坐标

所有适当的关系到位,以使这个工作中,他们肯定让我做这样的事情:

NSArray *trails = <query all trails> 

for (Trail *trail in trails) { 
    for (Segment *segment in trail.segments) { 
     for (Coordinate *coordinate in segment.coordinates) { 
      //do something with coords 
     } 
    } 
} 

从Django的背景的,我很高兴这一点,并承担尽可能少的查询将针对sqlite3的运行。错误!对这些循环中的每个对象都有一个查询。

我现在已经阅读了关于错误的核心数据文档,我明白发生了什么,但我真的很想知道处理这种情况的最佳实践是什么。我需要记忆中的每一个物体(坐标模型有大约100,000个物体),因为它们全部用于在地图上绘制轨迹。

我该如何处理这个超懒惰的加载?

+0

相关的(我从来没有与2级深想这一点,只有一个级别。):HTTP:// developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/Article/cdPerformance.html#//apple_ref/doc/uid/TP40003468-SW6 我相信,一对一地预取子对象,许多关系是可能的,并且在加载父对象之后批处理错误这样的关系也是可能的。如果我有机会,我可能会测试两种方法并发布比马丁R更完整的答案。 – 2013-07-29 14:04:12

回答

6

您可以使用NSFetchRequestsetRelationshipKeyPathsForPrefetching:方法。从文档:

预取允许核心数据,以获得相关对象在单个 撷取(每个实体),而不是它们的故障跳闸招致到 商店随后的接入为每个单独的记录。

因此在初始读取请求的路径,你可以添加

[request setRelationshipKeyPathsForPrefetching: 
    [NSArray arrayWithObjects:@"segments", @"segments.coordinates", nil]] 

+0

我研究了这种方法,但我认为它只适用于1:1的预取关系(如小孩预取它的父项,或者在这种情况下,段预取它的轨迹)。无论如何,我确实尝试过,没有运气。虽然谢谢! – jarcoal 2012-07-21 17:26:17

+0

我的答案中有一个错误:它必须是... arrayWithObjects:@“segments”,@“segments.coordinates”,nil!我只是试了一下,它似乎工作。如果将“-com.apple.CoreData.SQLDebug 3”设置为启动参数,则可以看到在初始获取请求中检索到了所有数据。这是通过3个sqlite查询完成的,与对象的数量无关。第一个sqlite查询是针对所有Trail对象的。第二个用于属于其中一个路径的所有Segment对象,第三个查询用于属于其中一个段的所有Coordinate对象。 – 2012-07-21 18:33:25

+0

我注意到这个错误,当你最初发布它和(想)我看到我以前的结果时纠正它,但现在我再试一次,它看起来像它的工作。谢谢! – jarcoal 2012-07-21 18:49:28