Pregunta

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

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

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

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

Cualquier idea sería apreciada, ¡gracias!

¿Fue útil?

Solución

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

El código para su clase se verá así:

-(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 que agregue un número de versión al codificar para darle flexibilidad para administrar los cambios en su formato de archivo en futuras versiones.

En mi clase, agregué un método conveniente para archivar mi objeto:

-(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 desarchivar 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;
}

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

Otros consejos

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

Si no, es una opción entre formato plist y NSCoding. plist requiere que pueda convertir sus objetos personalizados en algo amigable para plist y luego convertir el plist nuevamente en sus objetos, pero NSCoding es un poco más difícil de entender y no puede editarse (o examinarse) fácilmente a mano .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top