我正在使用这样的抓取请求从Core Data加载所有Node
个实体:
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Node"];
self.graphNodes = [self.viewController.objectContext executeFetchRequest:request error:&error];
实体Node
与NSOrderedSet
实体之间存在一对多有序(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
属性并并行使用数组?
答案 0 :(得分:1)
您已经走上正轨,但每个节点有1000个左右的关系,您需要走得更远。
托管对象上下文维护已获取对象的内部缓存。你可能需要尝试和#34;热身"通过在需要之前提前获取对象来缓存。尽早获取它们但不要使用它们。然后,当您需要它们时,再次获取,结果将来自缓存。
初始提取并不需要请求完整的对象。您可以将resultType
设置为managedObjectIDResultType
并获得相同的结果。
如果您使用后台队列,即不使用主队列的队列,这将最有效。在您需要结果之前,请告知后台队列在后台执行此提取,然后不要使用结果。