NSManagedObjectModel中的合并模型中的跨模型关系?
-
02-07-2019 - |
题
如果实体总是在通过合并相关模型创建的NSManagedObjectModel中使用,是否可以建模在单独的NSManagedObjectModel中定义的实体之间的关系?
例如,假设模型1定义了一个实体 Foo
,其关系(一对一) toBar
,而模型2定义了一个实体 Bar 代码>具有关系(一对一)
toFoo
。我将使用 - [NSManagedObjectModel mergedModelFromModels]
构建CoreData堆栈,合并模型1和模型2.是否有任何方法可以在数据建模器中或以编程方式定义这些关系,以便它们的行为就像它们一样模型间关系?
解决方案
模型1和模型2都不能在运行时加载,除非它们格式正确—即使 toBar
和 toFoo
关系有目的地。此外,如果模型1和模型2具有相同名称的模型,您将无法从它们创建合并模型;它们不会合并,它们会发生碰撞,这是一个错误。
但是,您可以手动使用 NSManagedObjectModel
API来加载每个模型,并手动创建包含两者中实体的新模型。 NSEntityDescription
和 NSPropertyDescription
类(及其子类)确实实现了 NSCopying
协议,因此在大多数情况下,您应该能够复制属性。每个组件模型都适用于您的整体模型。
此外, NS * Description
类都支持 userInfo
字典,您可以在Xcode的数据建模工具中编辑该字典,您可以使用它来标记目标作为替身的关系例如,在模型1中,您可以使用 userInfo
键 MyRealEntity
的 Bar
实体,并在创建合并模型时检查它,信号使用真实实体。
您还希望将替代关系置于您的替身实体中;这些将在合并后被真正的逆转所取代。但是,您不必在所有模型中完全复制您的替身实体;您只需要在实体中的实际模型中使用的反向关系。
因此,如果真正的 Foo
具有 name
属性,并且您的真实Bar具有 kind
属性,那么您的替换 Foo
和 Bar
不需要那些,只需要替代 toBar
和 toFoo
关系。
以下是一些代码,展示了我所说的内容:
- (NSManagedObjectModel *)mergeModelsReplacingDuplicates:(NSArray *)models {
NSManagedObjectModel *mergedModel = [[[NSManagedObjectModel alloc] init] autorelease];
// General strategy: For each model, copy its non-placeholder entities
// and add them to the merged model. Placeholder entities are identified
// by a MyRealEntity key in their userInfo (which names their real entity,
// though their mere existence is sufficient for the merging).
NSMutableArray *mergedModelEntities = [NSMutableArray arrayWithCapacity:0];
for (NSManagedObjectModel *model in models) {
for (NSEntityDescription *entity in [model entities]) {
if ([[entity userInfo] objectForKey:@"MyRealEntity"] == nil) {
NSEntityDescription *newEntity = [entity copy];
[mergedModelEntities addObject:newEntity];
[newEntity release];
} else {
// Ignore placeholder.
}
}
}
[mergedModel setEntities:mergedModelEntities];
return mergedModel;
}
这是因为在Core Data中复制 NS * Description
对象是关于关系的目标实体和逆(以及实体的子实体)的名称而不是按值。因此,虽然模型是可变的,也就是说,在它被设置为 NSPersistentStoreCoordinator
—的模型之前。你可以使用这样的技巧将你的模型分解成多个模型。