toBar
モデル 1 もモデル 2 も、整形式でない限り、つまり、とのtoFoo
関係に宛先がない限り、実行時にロードできません。さらに、モデル 1 とモデル 2 に同じ名前のモデルがある場合、それらからマージされたモデルを作成することはできません。それらは合体せず、衝突します。これはエラーです。
ただし、NSManagedObjectModel
API を手動で使用して各モデルをロードし、両方のエンティティを含む新しいモデルを手動で作成できます。およびクラス (NSEntityDescription
およびNSPropertyDescription
そのサブクラス) はNSCopying
プロトコルを実装しているため、ほとんどの場合、各コンポーネント モデルからモデル全体にプロパティをコピーするだけで済みます。
さらに、これらのNS*Description
クラスはすべてuserInfo
、Xcode のデータ モデリング ツールで編集できるディクショナリをサポートしています。これを使用して、リレーションシップの宛先にスタンドインとしてタグを付けるなどのことができます。たとえば、モデル 1 では、キーを持つBar
エンティティがあり、マージされたモデルを作成するときにそれをチェックして、代わりに実際のエンティティを使用するシグナルとして使用できます。userInfo
MyRealEntity
また、スタンドイン エンティティにスタンドイン逆関係を配置することもできます。これらは、マージ後に実際の逆数に置き換えられます。ただし、すべてのモデルでスタンドイン エンティティを完全に複製する必要はありません。スタンドインエンティティの実際のモデルで使用される逆の関係のみが必要です。
したがって、実物Foo
にname
属性があり、実物バーに属性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;
}
これが機能するのはNS*Description
、Core Data 内のオブジェクトのコピーが、リレーションシップの宛先エンティティおよびその逆に関して (およびエンティティのサブエンティティに対しても)、値ではなく名前によるためです。したがって、モデルが変更可能である間 (つまり、モデルとして設定される前) に、NSPersistentStoreCoordinator
このようなトリックを使用してモデルを複数のモデルに分割できます。