2009-03-15 19 views
10

Tengo un objeto personalizado que simplemente hereda de NSObject. Tiene 3 miembros: dos flotadores y un NSDate.Objetos personalizados persistentes

Mi aplicación va a tener una matriz con varios de estos objetos dando vueltas, y necesito persistir entre ejecuciones. ¿Cómo puedo lograr esto?

He pensado en usar una base de datos SQLite, pero estoy pensando que es un poco exagerada ya que la única consulta que haría sería select *.

En un mundo ideal, me gustaría utilizar un archivo xml plist. Sin embargo, no estoy seguro si puedo hacer esto con mi objeto personalizado. Sé que hay un conjunto de objetos de Lista de propiedades, y que NSArray viene bajo eso, pero writeToFile:atomically: solo funciona con objetos de lista de propiedades.

¡Cualquier pensamiento sería apreciado, gracias!

Respuesta

21

NSCoding hará exactamente lo que quiera. Te recomiendo que lo leas en los documentos de Apple, pero pensé que era bastante sencillo de usar. Su clase (y las clases secundarias) deberán implementar el protocolo NSCoding y deberá agregar los métodos -encodeWithCoder: y -initWithCoder: a sus objetos. La mayoría de las clases de framework comunes implementan NSCoding ya.

El código para su clase se verá algo como esto:

-(void) encodeWithCoder: (NSCoder*) coder { 
    [coder encodeInteger: versionValue forKey: versionKey]; 
    [coder encodeObject: myStuff forKey: myStuffKey]; 
} 

-(id) initWithCoder: (NSCoder*) coder { 
    self = [super init]; 
    if (! self) return nil; 
    myStuff = [[coder decodeObjectForKey: myStuffKey] retain]; 
    return self; 
} 

Se recomienda agregar un número de versión cuando se codifica para darle flexibilidad para gestionar los cambios en el formato de archivo en versiones futuras.

En mi clase, he añadido un método de conveniencia para archivar mi objetivo:

-(void) archiveToFile: (NSString*) path { 
    NSMutableData *data = [[NSMutableData alloc] init]; 
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData: data]; 
    [archiver encodeObject: self forKey: myArchiveKey]; 
    [archiver finishEncoding]; 
    [archiver release]; 
    [data writeToFile: path atomically: YES]; 
    [data release]; 
} 

y otro para anular el archivo o crear un nuevo objeto:

+(MyArchive*) newFromFile: (NSString*) path 
      orWithMyStuff: (MyStuff*) myStuff 
{ 
    NSData *data = [[NSData alloc] initWithContentsOfFile: path]; 
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData: data]; 
    MyArchive *myArchive = [unarchiver decodeObjectForKey: myArchiveKey]; 
    [unarchiver finishDecoding]; 

    if (myArchive) { 
    [myArchive retain]; 
    } else { 
    myArchive = [[MyArchive alloc] initWithStuff: myStuff; 
    } 
    [unarchiver release]; 
    [data release]; 
    return myArchive; 
} 

Debido a que su objeto de nivel superior es una NSArray, tendrá que modificar los dos últimos métodos para su caso, pero la mayoría del código repetitivo será el mismo.

+0

¿Y eso produciría un buen plist? Tenía la impresión de que escribir NSData solo produciría datos serializados y no un plist. – Jasarien

+0

Eso produce un archivo NSCoding, un archivo con copias preservadas de sus objetos, algo así como un archivo nib (pero no puede usar Interface Builder para editarlo). La "Guía de programación de archivos y serializaciones para Cocoa" en su documentación lo explicará. –

+0

De forma predeterminada, se archiva en una lista binaria, pero puede cambiarla a una lista XML si así lo desea. Desafortunadamente no es realmente legible por humanos, ya que contiene metadatos de clase y puntero, así como los datos de su objeto. –

0

Si va a querer recuperar un subconjunto de los objetos, SQLite es de lejos su mejor opción.

De lo contrario, se puede elegir entre formato plist y NSCoding. plist requiere que pueda convertir sus objetos personalizados en algo sencillo y luego convertir el plist de nuevo en sus objetos, pero NSCoding es un poco más difícil de envolver y no se puede editar (o examinar) fácilmente con la mano .

+0

No usaré subconjuntos. Solo necesito que persista la lista completa. ¿Cómo se puede convertir un objeto para que sea fácil de usar? Tenía entendido que hay un conjunto de Objetos de Lista de Propiedades y eso es todo. Mi objeto no está hecho de nada que no sea plistable ... – Jasarien

Cuestiones relacionadas