28

Tengo un diccionario de objetos; todos son objetos POCO que deberían ser serializables. ¿Qué técnica debo mirar para escribir esto en el disco? Estoy buscando la opción más simple para escribir algunas listas para guardar el estado.¿Cómo serializo un objeto simple en sdk de iPhone?

Creo que tengo 3 opciones.

  1. plist files. Sin embargo, esto parece estar limitado a solo almacenar objetos predefinidos (cadenas, números, etc.), no objetos (como una persona con un nombre y edad).

  2. CoreData. (Nuevo en 3.0) Esto funcionaría bien; sin embargo, mi modelo de datos debería cambiar para que esto funcione. Esto sería una repetición masiva y no estoy seguro si vale la pena el esfuerzo.

  3. SQLLite. Implemente una base de datos SQL simple para leer desde y hacia. He hecho la menor cantidad de inversión en esta, pero no quiero tener que 'reescribir' algunas de las funciones ORM de datos centrales.

Respuesta

14

Esto se hace de la misma manera que lo harías en Mac OS X: sus POCOs deben cumplir con el protocolo NSCoding. Ver here para una referencia conceptual, y here para la referencia NSCoding.

Si la información no es tan extensa y no tienes relaciones ridículamente complicadas entre tus objetos, escribir todo como un plist es probablemente tu mejor opción; es muy rápido de ejecutar y simple de implementar en tu código. Como dijiste, CoreData probablemente sea un lote de trabajo adicional para adaptar tu código, y sqlite realmente solo sirve para almacenar datos que son perfectos para ser almacenados en una base de datos relacional. Tenga en cuenta que sqlite también es más lento y utiliza más recursos que trabajar con listas binarias.

0

NSCoder es la expresión estándar de Cocoa para la serialización.

33

Para serializar un objeto personalizado, solo necesita cumplir con el protocolo NSCoding. Si el objeto se extiende NSObject todo lo que tiene que hacer (creo) es la implementación de éstos (por ejemplo, la persona objeto):

// Encode an object for an archive 
- (void)encodeWithCoder:(NSCoder *)coder 
{ 
    [super encodeWithCoder:coder]; 
    [coder encodeObject:name forKey:@“Name”]; 
    [coder encodeInteger:age forKey:@“Age”]; 
} 
// Decode an object from an archive 
- (id)initWithCoder:(NSCoder *)coder 
{ 
    self = [super initWithCoder:coder]; 
    name = [[coder decodeObjectForKey:@“Name”] retain]; 
    age = [coder decodeIntegerForKey:@“Age”]; 
} 

NSArray y NSDictionary ya aplicar métodos de serialización. Serializarán todos los objetos que contienen (si los objetos implementan la interfaz NSCoder, lo hacen si amplían NSObject). NSObject's encodeWithCoder y initWithCoder no hacen nada por defecto, de modo que a menos que implementes tu propio código en tus clases, nada se serializa.

Si tiene NSArray o NSDictionary de objetos puede sincronizar usando:

// Writing 
- (BOOL)writeToFile:(NSString *)aPath atomically:(BOOL)flag; 
- (BOOL)writeToURL:(NSURL *)aURL atomically:(BOOL)flag; 
// Reading 
- (id)initWithContentsOfFile:(NSString *)aPath; 
- (id)initWithContentsOfURL:(NSURL *)aURL; 
+0

nombre es objeto de tipo NSString por lo que desea conservar si desea utilizarlo, la edad es sólo números enteros primitiva – stefanB

+0

Puede no use writeToFile, writeToURL a menos que los objetos en el NSArray sean de tipo NSString, NSData, NSArray o NSDictionary. Siempre devolverá NO si intenta utilizar estos métodos en un NSArray con cualquier otro tipo de objeto. – Snickers

+0

@Snickers ¿estás hablando de NSArray lleno de otros tipos de objetos que implementan el protocolo 'NSCoding'? Porque eso es lo que expliqué más arriba. De lo contrario, no estoy seguro, es la respuesta de 3 años de edad, las cosas podrían haber cambiado, por favor, publique su respuesta. La persona que votó votará positivamente si es la mejor solución. – stefanB

Cuestiones relacionadas