我正在使用这样的获取请求从 Core Data 加载所有 Node
实体:
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Node"];
self.graphNodes = [self.viewController.objectContext executeFetchRequest:request error:&error];
实体 Node
与 Departure
实体具有一对多的有序 (NSOrderedSet
) 关系。我直接与他们合作:
self.nodeDepartures = node.departures.array;
Departure* departure = self.nodeDeparturesReference[index]; //Slow operation
但是最后一个操作执行起来很慢,我不明白为什么。在 XCode 的时间分析器中,我看到很多 NSSQLCore
方法的执行。这是一个 image调用的方法,但主要的是(按时间顺序):
[_NSFaultingMutableOrderedSet objectAtIndex:]
[_NSFaultingMutableOrderedSet willReadWithContents:]
[NSFaultHandler retainedFulfillAggregateFaultForObject:andRelationship:withContext:]
[NSPersistentStoreCoordinator(_NSInternalMethods) newValueForRelationship:forObjectWithID:withContext:error:]
... and cca. 20 more strange calls (check the image) ...
据我所知,发生了一些错误,程序无法找到所需的数据。我究竟做错了什么?请有任何想法。
编辑 1: 我发现问题出在故障关系中(更多关于故障 here )。使用获取节点的新方法“解决”了这个问题:
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Node"];
[request setReturnsObjectsAsFaults:NO];
[request setRelationshipKeyPathsForPrefetching:@[ @"departures" ]];
self.graphNodes = [self.viewController.objectContext executeFetchRequest:request error:&error];
无论如何,这对我来说不是一个好的解决方案,因为这种预取需要很多时间,但我需要立即使用 Nodes
数组。有没有办法在后台线程中预取 departures
属性并并行使用数组?
最佳答案
您走在正确的轨道上,但是每个节点有 1000 个左右的关系,您需要走得更远。
托管对象上下文维护获取对象的内部缓存。您可能需要在需要之前通过提前获取对象来尝试“预热”缓存。尽早获取它们但不要使用它们。稍后当您需要它们时,再次获取,结果将从缓存中获取。
初始提取不需要请求完整的对象。您可以将 resultType
设置为 managedObjectIDResultType
并获得相同的结果。
如果您使用后台队列(即不使用主队列的队列),这将发挥最佳作用。在您需要结果之前,告诉后台队列在后台执行此提取,然后不要使用结果。
关于ios - 核心数据缓慢获取关系对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49519760/