objective kits development developer apple app objective-c cocoa core-data osx-lion nspersistentdocument

objective-c - development - xcode kits



MigraciĆ³n ligera de un NSPersistentDocument (4)

Intento hacer una migración liviana de una tienda SQLite en Core Data. Trabajando en Lion 10.7.3 con Xcode 4.3.1.

En mi subclase NSPersistentDocument (AccountDocument), he reemplazado el método utilizado para configurar el coordinador de tienda persistente para que obtenga 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 por ese consejo: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html )

Cuando ejecuto la aplicación, falla en la implementación de -managedObjectModel 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

Por lo que puedo decir de la documentación, la implementación predeterminada se ve así:

- (id)managedObjectModel { NSManagedObjectModel *result = [NSManagedObjectModel mergedModelFromBundles:nil]; return result; }

Entonces para depurar el problema un poco más, superé 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 seguí los consejos de Marcus Zarra para limpiar el proyecto, de modo que no haya paquetes perdidos de .mom o .momd en el paquete de la aplicación: Using fusionedModelFromBundles: y control de versiones (CoreData) ) Sin embargo, la aplicación continúa fallando mientras se carga el modelo desde la url.

Comprobé que 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 idea de qué. Cualquier ayuda sería muy apreciada…

Actualizar:

Según la sugerencia de Martin (y una verificación de la documentación de NSPersistentDocument) intenté usar este código para el descriptor 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; }

Todavía se está cayendo ...

Actualizar

Después de algunas sugerencias en Twitter, actualicé a Xcode 4.3.2, pero los problemas persisten.

ACTUALIZACIÓN DE RAGE

Acabo de crear el paquete de 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 paquete de archivo AccountDocument2.xcdatamodeld nuevamente 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 critican a 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 estar 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.

Se trata de esta actualización

Más pruebas de que este es un error grave con el compilador de modelos de datos (MOMC) en Xcode 4.3.2: si copio el paquete .momd de la carpeta de recursos creada por Xcode 4.2 en mi proyecto y los agrego a la compilación como un archivo de copia fase de construcción, 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 (según la sugerencia de Marcus a continuación). 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 debe tenerse en cuenta que este error no está aislado en NSPersistentDocument (como pensé originalmente cuando comencé esta pregunta). Puedo causar que una aplicación se cuelgue utilizando simplemente [[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 para enviar un Radar ...

Actualización de radar

Acabo de enviar este Radar:

http://www.openradar.me/11184500

La actualización de Oh Crap It Must Be Lion

Acabo de descargar e instalar 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 puede instalar Xcode 4.2.1 porque el certificado utilizado para firmar DeveloperTools.pkg ha expirado. Solo Xcode 4.2 funcionará).

Si tienes menos de NDA, también encontrarás que las herramientas beta tampoco son útiles.

Espero que tengas una copia de Snow Leopard con Xcode 4.2 sentado: http://furbo.org/2012/03/28/vmware-for-developers/

Las solicitudes de obtención de tareas WTF tienen que ver con la actualización de atributos y entidades revisadas

A través de 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 pblicas).

La raíz del problema es una única 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.


Creo que necesita almacenar el modelo de objetos gestionados en una variable de instancia. Usted está devolviendo un objeto liberado automáticamente, que es lo que probablemente esté causando el acceso incorrecto.



Los recursos compilados de .momd se pueden cargar después de que se cambie una solicitud de búsqueda "existingPartner" desde:

name == $name

a:

name == $NAME

Es contra intuitivo que una parte del modelo de objetos que no afecta la persistencia de los datos interrumpe el control de versiones y la migración ligera. De la documentación se desprende claramente que este no debería ser el caso:

La perspectiva de Core Data sobre el control de versiones es que solo le interesan las características del modelo que afectan la persistencia.

Utilice el poder de CHOCKLOCK para corregir sus Solicitudes de obtención o elimínelas por completo y confíe en NSPredicates creados en el código .


Según su teoría de que es un problema con el MOMC, ¿tiene alguna regla de validación en la madre?

He visto informes donde las reglas de validación no sobreviven al 4.x MOMC.