我有一个CoreData数据库,里面有大约500,000枚邮票和86.000系列。我必须从使用JSON的web api下载它们。将邮票和系列添加到核心数据中没有问题。但在两者之间建立关系时我遇到了麻烦。
每枚邮票都有一个系列,每个系列可以有多个邮票。如上面我的数据模型图片所示。
我需要有效和快速地建立两者之间的关系。当我做一些研究时,我偶然发现了这个网站https://www.objc.io/issues/4-core-data/importing-large-data-sets-into-core-data/我最感兴趣的那篇:
在建立关系时经常会出现类似的问题 新导入的对象。使用获取请求获取每个相关的 对象独立是非常低效的。有两种可能 解决这个问题的方法:要么我们分批解决关系 我们如何首先导入对象,或者我们缓存 已导入对象的objectID。解决关系 批量允许我们大大减少获取请求的数量 一次获取许多相关对象所需。别担心 潜在的长谓词如:
[NSPredicate predicateWithFormat:@"identifier IN %@", identifiersOfRelatedObjects];
在IN(...)子句中解析具有许多标识符的谓词是 总是比为每个对象转到磁盘更有效 独立。但是,还有一种方法可以避免获取请求 完全(至少如果你只需要建立关系 在新导入的对象之间)。如果缓存所有的objectID 导入的对象(在大多数情况下真的不是很多数据), 您可以稍后使用它们来检索相关对象的故障 objectWithID:
// after a batch of objects has been imported and saved for (MyManagedObject *object in importedObjects) { objectIDCache[object.identifier] = object.objectID; } // ... later during resolving relationships NSManagedObjectID objectID = objectIDCache[object.foreignKey]; MyManagedObject *relatedObject = [context objectWithID:objectId]; object.toOneRelation = relatedObject;
请注意,此示例假定identifier属性是唯一的 跨所有实体类型,否则我们将不得不考虑 我们缓存的方式中不同类型的重复标识符 对象ID。
但我不知道他们的意思是什么,有人可以对此作出更多解释。最好是在Swift中,因为这是我理解的最好的语言,也是我正在创建我的应用程序的语言。 当然其他建议也没关系。 注意,离开CoreData不再是一个选项了。
答案 0 :(得分:3)
在两个对象之间建立关系的任务涉及掌握这两个对象。考虑到它们已经在Core Data中创建,您可以使用类似
的谓词执行获取请求@"countryID == %@", countryObjectData[@"id"]
你会得到它们。但是如果你需要建立五十万个关系,你将不得不执行一百万个获取请求。这很慢。
按NSManagedObject
检索NSManagedObjectID
明显比按属性值搜索更快。在开始解析之前,您可以按server key -> objectID
对的形式按实体构建所有Core Data对象的缓存。
self.cache = [NSMutableDictionary dictionaryWithCapacity:self.managedObjectModel.entities.count];
NSExpressionDescription *objectIdDescription = [[NSExpressionDescription alloc] init];
objectIdDescription.name = @"objectID";
objectIdDescription.expression = [NSExpression expressionForEvaluatedObject];
objectIdDescription.expressionResultType = NSObjectIDAttributeType;
NSString *key = @"serverID";
for (NSEntityDescription *entity in self.managedObjectModel.entities) {
NSMutableDictionary *entityCache = [NSMutableDictionary dictionary];
self.cache[entity.name] = entityCache;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entity.name];
request.resultType = NSDictionaryResultType;
request.propertiesToFetch = @[key, objectIdDescription];
NSArray *result = [self.context executeFetchRequest:request error:nil];
for (NSDictionary *item in result) {
id value = item[key];
NSManagedObjectID *objectID = item[@"objectID"];
entityCache[value] = objectID;
}
}
拥有该缓存,您可以获得如下对象:
id serverKey = countryObjectData[@"id"];
NSManagedObjectID *objectID = self.cache[@"Country"][serverKey];
Country *country = [self.context objectWithID:objectID]
它快得多。
在解析JSON时创建新对象时,需要在获取permanent ID后将其服务器密钥和objectID对添加到缓存中。删除对象时从缓存中删除该对。