Estoy tratando de hacer una migración ligera de una tienda SQLite en Core Data. Trabajando en Lion 10.7.3 con Xcode 4.3.1.Migración ligera de NSPersistentDocument
En mi subclase NSPersistentDocument (AccountDocument), que ha redefinido el método utilizado para configurar el coordinador de almacenamiento persistente para que llegue las opciones adecuadas para la migración:
- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error
{
NSMutableDictionary *newStoreOptions;
if (storeOptions == nil) {
newStoreOptions = [NSMutableDictionary dictionary];
}
else {
newStoreOptions = [storeOptions mutableCopy];
}
[newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
BOOL result = [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:newStoreOptions error:error];
return result;
}
(Gracias a Malcolm Crawford para ese consejo: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html)
Cuando ejecuto la aplicación, se produce un error en la aplicación de NSPersistentDocument de -managedObjectModel
:
* thread #1: tid = 0x2703, 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16, stop reason = EXC_BAD_ACCESS (code=13, address=0x0)
frame #0: 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16
frame #1: 0x00007fff8935e975 CoreData`-[NSKnownKeysDictionary1 _setValues:retain:] + 197
frame #2: 0x00007fff8935f288 CoreData`_newReadModelFromBytes + 648
frame #3: 0x00007fff8935b93e CoreData`+[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) _newModelFromOptimizedEncoding:error:] + 9310
frame #4: 0x00007fff89359451 CoreData`-[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) initWithContentsOfOptimizedURL:] + 305
frame #5: 0x00007fff89358d7b CoreData`-[NSManagedObjectModel initWithContentsOfURL:] + 443
frame #6: 0x00007fff893e9519 CoreData`+[NSManagedObjectModel mergedModelFromBundles:] + 377
frame #7: 0x00007fff8ded7037 AppKit`-[NSPersistentDocument managedObjectModel] + 301
frame #8: 0x00007fff8ded70b3 AppKit`-[NSPersistentDocument managedObjectContext] + 75
frame #9: 0x00007fff8ded6e3f AppKit`-[NSPersistentDocument _persistentStoreCoordinator] + 18
frame #10: 0x00007fff8ded6b5d AppKit`-[NSPersistentDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 51
frame #11: 0x0000000100003193 BeanCounter`-[AccountDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 419 at AccountDocument.m:298
De lo que puedo decir de la documentación, la implementación por defecto se ve algo como esto:
- (id)managedObjectModel
{
NSManagedObjectModel *result = [NSManagedObjectModel mergedModelFromBundles:nil];
return result;
}
Así que para depurar el problema un poco más, me hizo caso omiso de ese método con esto:
- (id)managedObjectModel
{
NSBundle *bundle = [NSBundle mainBundle];
NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"];
NSManagedObjectModel *result = [[[NSManagedObjectModel alloc] initWithContentsOfURL:url] autorelease];
return result;
}
(Gracias a Jeff LaMarche por la idea: http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html)
El paquete y la url apuntan a los lugares que espero (y he seguido el consejo de Marcus Zarra de limpiar el proyecto para que no haya ningún .mom o .momd perdido) paquetes en la aplicación paquete de ación: Using mergedModelFromBundles: and versioning (CoreData)). Sin embargo, la aplicación continúa fallando mientras se carga el modelo desde la url.
He comprobado que el AccountDocument2.xcdatamodeld es un paquete que tiene dos modelos para el control de versiones: AccountDocument 2.xcdatamodel y (el original) AccountDocument.xcdatamodel. El menú emergente "Modelo de datos base versionado" en las propiedades del archivo se establece en "AccountDocument 2".
La única diferencia entre los dos modelos es que una entidad tiene un atributo adicional (y opcional). Según entiendo, califica el modelo para una migración ligera.
Obviamente, estoy haciendo algo mal aquí, pero no tengo ni idea de qué. Cualquier ayuda sería muy apreciada ...
Actualización: la sugerencia de
por Martin (y una comprobación de la documentación NSPersistentDocument) He intentado utilizar el código para el método de acceso:
- (id)managedObjectModel
{
static id sharedManagedObjectModel = nil;
if (sharedManagedObjectModel == nil) {
NSBundle *bundle = [NSBundle mainBundle];
NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"];
sharedManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url];
}
return sharedManagedObjectModel;
}
Aún estrellarse ...
actualización
Después de algunas sugerencias en Twitter, actualicé a Xcode 4.3.2, pero los problemas persisten.
RAGE ACTUALIZACIÓN
acabo de crear el paquete modelo versionado (AccountDocument2.xcdatamodeld) usando Xcode 4.2 en Snow Leopard. Después de compilar y ejecutar la aplicación, todo funciona como se esperaba.
Luego tomé el AccountDocument2.paquete de archivos xcdatamodeld de vuelta a Lion y Xcode 4.3.2. Cuando construyo y ejecuto la aplicación, continúa bloqueándose mientras se carga el recurso .momd. Sí niños, eso significa que Xcode 4.3.x y el compilador del modelo de datos (MOMC) tienen la culpa. No veo una solución alternativa que no sea hacer todas mis compilaciones en Snow Leopard.
No soy de los que golpean Xcode 4, pero cuando nos encontramos en una situación donde la cadena de herramientas no puede producir un archivo opaco (.mom y .momd) a partir de una especificación opaca (.xcdatamodel y .xcdatamodeld) es bastante difícil ser optimista sobre el estado de las herramientas de Mac y iOS. Es ridículo que un componente central de estas plataformas se rompa en la medida en que no puedo construir y ejecutar mi aplicación en la última versión del SDK y las herramientas para desarrolladores.
Ha llegado a esta actualización de
Más pruebas de que este es un error grave con el modelo del compilador de datos (MOMC) en Xcode 4.3.2: si copio el paquete .momd de la carpeta de recursos creado por Xcode 4.2 en mi proyecto y los agrega a la compilación como una fase de compilación de Copiar archivos, la aplicación funciona bien.
También realicé algunas pruebas en las que eliminé las reglas de validación y los valores predeterminados para los Atributos de las distintas Entidades. Sin cambios, el compilador aún crea un .momd inválido. También traté de crear un modelo versionado donde NADA cambiara: el .momd compilado continuó bloqueándose. Entonces, lo que tenga en sus modelos actuales (y los datos que representan) es la fuente del problema.
También hay que tener en cuenta que este error no está aislado en NSPersistentDocument (como pensé al principio cuando comencé esta pregunta). Puedo causar que una aplicación se cuelgue utilizando [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]
.
Por ahora, voy a editar/versionar mis modelos usando Xcode 4.2 en Snow Leopard y mover los recursos compilados a Xcode 4.3.2 en Lion. Si usa Core Data de alguna manera, le sugiero que haga lo mismo hasta que se solucione este error. Créeme, pasarás días tratando de descubrir qué demonios está pasando si no lo haces.
Ahora que presente un radar ...
Radar actualización
simplemente presenté este radar:
http://www.openradar.me/11184500
la mierda Oh Debe ser león actualización
Acabo de descargar una nd instaló el Xcode 4.2 para herramientas Lion desde http://developer.apple.com/downloads. La aplicación de muestra utilizada en el radar aún se bloquea.
(Nota: no se puede instalar Xcode 4.2.1 debido a que el certificado utilizado para firmar el DeveloperTools.pkg ha expirado Sólo Xcode 4.2 funcionará..)
Si estás bajo NDA usted también descubre que las herramientas beta tampoco son útiles.
Espero que tengas una copia de Snow Leopard con Xcode 4.2 sentados alrededor: http://furbo.org/2012/03/28/vmware-for-developers/
La WTF No Fetch Las solicitudes tienen que ver con las entidades versionado y atributos de actualización
Via Evadne Wu en Twitter:
https://twitter.com/#!/evadne/status/187625192342818818
Y cómo lo hizo:
https://twitter.com/#!/evadne/status/187629091518816258
(los archivos .mom son listas binarias.)
El origen del problema es una sola solicitud de obtención. La forma en que esto se traduce en una migración de datos de un modelo a otro es para que un ingeniero en Apple lo descubra.
¿Estás usando ARC en la clase que define 'configurePersistentStoreCoordinatorForURL :::::'? Si no, estás filtrando la copia que haces de 'storeOptions'. –
Dependiendo de si la storeOptions existente está presente, newStoreOptions se conservará (si llama a [storeOptions mutableCopy]) o se liberará automáticamente si sigue la ruta que llama a [NSMutableDictionary dictionary] –
Peter tiene razón de que hay una pérdida de newStoreOptions, pero no lo hace Realmente importa ya que solo revisé la ruta del código y storeOptions venía como nulo. Esta no es la fuente del problema al cargar el modelo de todos modos (los modelos no se pueden cargar, mucho menos migrar). – chockenberry