Ni el modelo 1 ni el modelo 2 podrán cargarse en tiempo de ejecución a menos que estén bien formados, es decir, a menos que las relaciones toBar
y toFoo
tengan destinos. Además, si el modelo 1 y el modelo 2 tienen modelos con nombre idéntico, no podrá crear un modelo fusionado a partir de ellos; no se fusionarán, colisionarán, lo cual es un error.
Sin embargo, puede usar la API NSManagedObjectModel
manualmente para cargar cada modelo y crear un nuevo modelo a mano que contenga entidades de ambos. Las clases NSEntityDescription
y NSPropertyDescription
(y sus subclases) implementan el protocolo NSCopying
por lo que, en la mayoría de los casos, solo debe poder copiar las propiedades desde cada modelo de componente a su modelo general.
Además, todas las clases NS*Description
admiten un diccionario userInfo
que puede editar en la herramienta de modelado de datos de Xcode, que puede usar para marcar el destino de una relación como un suplente. Por ejemplo, en el modelo 1 podría tener una entidad Bar
con una clave userInfo
MyRealEntity
y verificarla al crear su modelo fusionado, como una señal para usar la entidad real en su lugar.
También deseará establecer relaciones inversas independientes con sus entidades de reserva; estos serán reemplazados con inversas reales después de la fusión. Sin embargo, no tiene que replicar por completo sus entidades de reserva en todos los modelos; solo necesitas las relaciones inversas usadas en tu modelo real en un stand en entidad.
Por lo tanto, si su verdadera Foo
tiene un atributo name
, y su verdadera barra tiene un atributo kind
, el sustituto de Foo
y Bar
no se necesita esos, solo suplente toBar
y toFoo
relaciones.
Aquí hay algo de código que muestra lo que estoy hablando:
- (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;
}
Esto funciona porque la copia de NS*Description
objetos en la base de datos es por nombre en lugar del valor con respecto a la entidad de destino de una relación e inversa (y a los subentidades de una entidad también). Por lo tanto, mientras que un modelo es mutable, es decir, antes de que se establezca como el modelo para un NSPersistentStoreCoordinator
, puede usar trucos como este para dividir su modelo en varios modelos.