8

Estoy migrando un modelo CoreData entre dos versiones de una aplicación. Estaba almacenando datos binarios como blobs en la versión anterior y quiero sacarlos de los blobs para el rendimiento. Mi problema es que, durante la migración, parece que Core Data carga todo en la memoria, lo que da lugar a Low Memory Warnings y luego a mi aplicación.Sin memoria mientras realiza la migración de datos centrales

documentación de Apple sugiere lo siguiente: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmCustomizingTheProcess.html#//apple_ref/doc/uid/TP40005510-SW9

Sin embargo, parece que confiar en el hecho de que los objetos grandes se aplican diferentes mapeo. En mi caso, todos los objetos son básicamente los mismos y se debe aplicar el mismo mapeo a cada uno de ellos. No veo en este caso cómo podría aplicar su técnica.

¿Cómo debo manejar una migración con objetos muy grandes?

Respuesta

2

Supongo que tiene un montón de cambios que desea hacer, además de sacar los datos de blobs. Mi sugerencia es hacer la migración en algunas etapas. Estoy pensando en voz alta aquí, así que podría ser posible mejorar esto. Esto requiere que uses SQLite.

para hacer este trabajo, vas a tener tres versiones de su modelo:

  1. El modelo original
  2. El modelo con el atributo eliminado (y posiblemente con un identificador único added-- especial véase más adelante)
  3. el modelo con todos los cambios que ha realizado, incluyendo la adición de la nueva entidad y las relaciones que sustituye el atributo

la razón para ello es que el tra La nsición de la versión 1 a 2 debería ser factible con una migración ligera y automática. En ese caso, Core Data no necesita cargar nada en la memoria; solo emite sentencias SQL para realizar los cambios directamente en la base de datos.

Entonces, comienza configurando su coordinador de tienda persistente utilizando la versión del modelo anterior. Una vez que hayas cargado los datos, revisa todos los objetos que estás migrando, extrae el atributo binario y escríbelo de alguna forma. Puede usar una solicitud de recuperación con lotes y drenaje de agrupación de autorrelease regular para asegurarse de no utilizar demasiada memoria para objetos temporales. Almacene los datos en el directorio que obtiene con NSCachesDirectory. Obviamente, querrá almacenar los datos de una manera que le permita relacionarlos de nuevo con el IDObjeto gestionado del objeto.

Luego, cierra todo y solicita a Core Data que migre la tienda de la versión 1 a la versión 2. Consulte this link para obtener más información. Abra la tienda con la versión 2.

Es posible que tenga que agregar un paso donde asigne algún tipo de ID único a cada objeto, porque no estoy seguro si Core Data mantiene ID de objeto cuando no es liviano migración. Si necesita hacer esto, su modelo de versión 2 agregará un nuevo atributo al objeto del que está sacando los datos binarios que sería opcional o que tiene un valor predeterminado establecido. Debido a que la migración ligera no debe cambiar los ID de Objeto gestionado, puede guardar la asignación de su nueva Id. Única a los ID de Objeto gestionado que guardó junto con los datos binarios hace dos párrafos.

Guarde los datos y cierre la tienda.

Abra la tienda y realice una migración de la versión 2 a la versión 3, que básicamente debería ser el código que ya había escrito antes de publicar la pregunta. Una vez que la tienda esté abierta, agregue todos los objetos que guardó de la tienda de la versión 1 y configure las relaciones con los datos que guardó en el camino.

Simple, ¿verdad?

+0

Gracias Jacques, en realidad esto me dio una buena pista y he hecho algo similar sin ir tan bajo como SQLite. Pero me estoy creando dos tiendas diferentes y creando objetos en cada una de ellas. La parte difícil es asegurarse de que Core Data convierta los objetos en fallas tan pronto como se usen. – Kamchatka

Cuestiones relacionadas