核心数据缓慢获取关系对象

时间:2018-03-27 18:10:22

标签: ios objective-c xcode core-data

我正在使用这样的抓取请求从Core Data加载所有Node个实体:

NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Node"];
self.graphNodes = [self.viewController.objectContext executeFetchRequest:request error:&error];

实体NodeNSOrderedSet实体之间存在一对多有序Departure)关系。我直接与他们合作:

self.nodeDepartures = node.departures.array;
Departure* departure = self.nodeDeparturesReference[index]; //Slow operation

但最后一次操作执行得非常慢,我不明白为什么。在XCode的时间分析器中,我看到了一些NSSQLCore方法的大量执行。这是一个zaph被调用的方法,但主要的是(按时间顺序):

[_NSFaultingMutableOrderedSet objectAtIndex:]
[_NSFaultingMutableOrderedSet willReadWithContents:]
[NSFaultHandler retainedFulfillAggregateFaultForObject:andRelationship:withContext:]
[NSPersistentStoreCoordinator(_NSInternalMethods) newValueForRelationship:forObjectWithID:withContext:error:]
... and cca. 20 more strange calls (check the image) ...

据我所知,发生了一些错误,程序无法找到所需的数据。我究竟做错了什么?请问任何想法。

编辑1: 我发现这个问题出现了错误的关系(更多关于错误image)。问题是解决了#34;用新方法获取节点:

NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Node"];
[request setReturnsObjectsAsFaults:NO];
[request setRelationshipKeyPathsForPrefetching:@[ @"departures" ]];
self.graphNodes = [self.viewController.objectContext executeFetchRequest:request error:&error];

无论如何,对我来说是一个很好的解决方案,因为这个预取需要花费很多时间,但我需要立即使用Nodes数组。有没有办法在后台线程中预取departures属性并并行使用数组?

1 个答案:

答案 0 :(得分:1)

您已经走上正轨,但每个节点有1000个左右的关系,您需要走得更远。

托管对象上下文维护已获取对象的内部缓存。你可能需要尝试和#34;热身"通过在需要之前提前获取对象来缓存。尽早获取它们但不要使用它们。然后,当您需要它们时,再次获取,结果将来自缓存。

初始提取并不需要请求完整的对象。您可以将resultType设置为managedObjectIDResultType并获得相同的结果。

如果您使用后台队列,即不使用主队列的队列,这将最有效。在您需要结果之前,请告知后台队列在后台执行此提取,然后不要使用结果。