2010-12-28 12 views
29

He estado buscando un código de ejemplo sobre cómo almacenar un NSArray en Core Data por un tiempo, pero no he tenido suerte. ¿Alguien me importaría señalarme algún tutorial o ejemplo, o mejor aún, escribir una muestra simple como respuesta a esta pregunta? He leído this pero no muestra un ejemplo de cómo implementar un atributo transformable que es NSArray. ¡Gracias por adelantado!Almacenar NSArray en el código de muestra de datos básicos?

+0

Consulte http://stackoverflow.com/questions/29825604/how-to-save-array-to-coredata/40101654#40101654 –

Respuesta

25

No almacena un NSArray de forma nativa en Core Data. Debe transformar los valores almacenados dentro de la matriz en algo que Core Data pueda usar, y luego guardar los datos en la tienda para que pueda empujar y tirar a su NSArray según sea necesario.

+10

Votado con ningún comentario? No es terriblemente útil, especialmente porque la respuesta no es realmente incorrecta. –

+0

que algo que los datos centrales pueden usar sería otra 'entidad' en su modelo de datos central que está conectada a su 'entidad' original a través de una relación de muchos (suponiendo que todos sus objetos NSArray son de la misma clase). –

+6

La pregunta es acerca de * atributos transformables *, que son una forma totalmente apropiada de almacenar un NSArray u otro objeto complejo en Core Data. – quellish

7

La respuesta de Philip es correcta. No almacena arrays en Core Data. Es totalmente contrario a lo que Core Data está hecho. La mayoría de las veces, no necesita la información de la matriz, sino una y la puede cargar dinámicamente Core Data. En el caso de las colecciones, no hay diferencia si itera a través de una matriz de sus propiedades o de una matriz de resultados obtenidos en un NSSet (que básicamente es solo una matriz).

Aquí está la explicación de lo que dijo Philip. No puede almacenar una matriz directamente, pero puede crear una lista de propiedades a partir de ella. Hay un método en todos los Arraytypes NS que le da una cadena agradable y limpia y cadenas de amor de datos centrales. Lo bueno de las listas de propiedades almacenadas como cadenas es que pueden convertirse en lo que eran. Hay un método para eso en NSString. Tataaa ...

Hay un precio, por supuesto. Las matrices como listas de propiedades pueden volverse gigantescas y eso no funciona bien con dispositivos iOS donde la memoria RAM es limitada. Intentar guardar una matriz en los datos centrales indica un diseño deficiente de la entidad, especialmente para datos de gran tamaño. Una pequeña matriz está bien por razones de velocidad.

Otra manera, que consume menos espacio, es utilizar listas de propiedades binarias. Aquellos que se acercan a los tamaños zip cuando se almacenan en Core Data o directamente en el sistema de archivos. Lo malo es que no puedes simplemente abrirlos y leerlos como un archivo XML o JSON. Para el desarrollo, prefiero algo legible por humanos y para lanzar la versión binaria. Una constante vinculada al valor DEBUG en el preprocesador se ocupa de eso, por lo que no tengo que cambiar mi código.

+1

No asuma que el póster original votó respuestas abajo, le da un sabor agrio a una publicación ya agria. Gracias por la buena explicación sin embargo. – Stunner

+3

Ouch. Sí, lo traduje mal y respondí más emocionalmente. Lo siento mucho por eso. –

1

Core Data almacena instancias de NSManagedObject o subclases de las mismas. NSManagedObject en sí mismo es muy parecido a un diccionario. Para muchas relaciones entre objetos se representan como conjuntos. Core Data no tiene una lista ordenada que corresponda a una matriz. En cambio, cuando recupera objetos de un almacén de datos centrales, utiliza una solicitud de búsqueda. Esa solicitud de obtención puede especificar uno o más descriptores de clasificación que se utilizan para ordenar los objetos, y los objetos devueltos por una solicitud de recuperación se almacenan en una matriz.

Si conservar el orden de los objetos es importante, deberá incluir un atributo en su entidad que pueda usarse para ordenar los objetos cuando los obtenga.

37

Si realmente necesita hacerlo, codifique como datos. Simplemente creé un archivo nuevo llamado receive como NSData (datos binarios).

Luego, en la puesta en práctica NSManagedObject:

-(void)setReceiveList:(NSArray*)list{ 
    self.receive = [NSKeyedArchiver archivedDataWithRootObject:list]; 
} 

-(NSArray*)getReceiveList{ 
    return [NSKeyedUnarchiver unarchiveObjectWithData:self.receive]; 
} 
+0

Es cierto, mejor que almacenarlo como cadena –

+0

buen comentario para darme una pista. – tounaobun

28

atributos transformables son la forma correcta de persistir valores de los objetos de otro modo no compatibles en la base de datos (como NSArray).De Core Data Programming Guide: Non-Standard Persistent Attributes:

La idea detrás de atributos transformables es que tiene acceso a un atributo como un tipo no estándar, pero detrás de las escenas de Datos Básicos utiliza una instancia de NSValueTransformer para convertir el atributo hacia y desde una instancia de NSData. Core Data luego almacena la instancia de datos en la tienda persistente.

Un atributo transformable utiliza un NSValueTransformer para almacenar un objeto no compatible en el almacenamiento persistente. Esto permite que Core Data almacene casi cualquier cosa que pueda representarse como NSData, lo que puede ser muy útil. Lamentablemente, los atributos transformables no pueden coincidir en un predicado ni usarse en los resultados de clasificación con NSSQLiteStoreType. Esto significa que los atributos transformables son útiles solo para el almacenamiento, no para el descubrimiento de objetos.

El transformador predeterminado permite que cualquier objeto que admita NSCoding (o NSSecureCoding) se almacene como un atributo transformable. Esto incluye NSArray, UIColor, UIImage, NSURL, CLLocation, y muchos otros. No se recomienda utilizar esto para datos que pueden ser arbitrariamente grandes, ya que pueden tener un impacto significativo en el rendimiento al consultar la tienda. Las imágenes, por ejemplo, no se ajustan a los atributos transformables: son grandes bolsas de bytes que fragmentan la tienda. En ese caso, es mejor utilizar las capacidades de almacenamiento de registros externos de Core Data, o almacenar los datos por separado como un archivo, y almacenar la URL en el archivo en Core Data. Si debe almacenar un UIImage en Core Data, asegúrese de conocer las compensaciones involucradas.

Creación de un atributo transformable es fácil:

• En el Editor de Core Data Model Xcode, seleccione el modelo de atributo que desea modificar. En el inspector del lado derecho, configure el tipo de atributo como "Transformable". Puede dejar el campo "Nombre" en blanco para usar el transformador predeterminado. Si estuviera usando un transformador personalizado, ingrese el nombre de la clase aquí y registre la clase usando +[NSValueTransformer setValueTransformer:forName:] en algún lugar de su código.

Core Data Model Editor Transformable Attribute

• En la cabecera subclase NSManagedObject declaran la propiedad que describe el atributo transformable con el tipo correcto. En este caso, estamos usando NSArray:

@property (nonatomic, retain) NSArray *transformedArray;

• En el archivo de implementación NSManagedObject subclase la propiedad debe ser dinámico:

@dynamic transformedArray;

y ya está. Cuando se pasa un objeto de valor NSArray a setTransformedArray:, esa matriz queda retenida por el objeto. Cuando se guarde el contexto, Core Data transformará el NSArray en NSData utilizando el NSValueTransformer descrito en el modelo. Los bytes NSData se guardarán en la tienda persistente.

+0

¿Cómo puedo convertir un transformable (NSObject) a NSArray? – Nil

+0

Quellish: excelente respuesta, pero ¿puedo molestarlo para que amplíe su respuesta a los bloques de código de la portada como objetos transformables sin editar las definiciones de categorías generadas automáticamente que proporciona XCode del modelo? Prácticamente no hay datos sobre esto en ninguna parte y, al igual que el que pregunta, estoy completamente perdido en cuanto a cómo lograr esto. Gracias de antemano si no te importa. – VectorVictor

+0

@VectorVictor No estoy seguro de lo que quiere decir con bloques de código como objetos transformables – quellish

Cuestiones relacionadas