Domanda

Ho un oggetto personalizzato che eredita semplicemente da NSObject. Ha 3 membri: due float e un NSDate .

La mia app avrà un array con un certo numero di questi oggetti in movimento, e devo persistere tra una corsa e l'altra. Come posso farlo?

Ho pensato di usare un db di SQLite, ma sto pensando che sia un po 'eccessivo poiché l'unica query che farei sarebbe select * .

In un mondo ideale mi piacerebbe usare un file plist xml. Non sono sicuro di poterlo fare con il mio oggetto personalizzato. So che esiste una serie di oggetti Elenco proprietà e che NSArray rientra in questo, ma writeToFile: atomically: funziona solo con oggetti elenco proprietà.

Ogni pensiero sarebbe apprezzato, grazie!

È stato utile?

Soluzione

NSCoding farà esattamente quello che vuoi. Ti consiglio di leggerlo nei documenti di Apple, ma ho pensato che fosse piuttosto semplice da usare. La tua classe (e le eventuali classi secondarie) dovranno implementare il protocollo NSCoding e dovrai aggiungere -encodeWithCoder: e -initWithCoder: metodi per i tuoi oggetti. La maggior parte delle classi comuni di framework implementa già NSCoding .

Il codice per la tua classe sarà simile a questo:

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

Si consiglia di aggiungere un numero di versione durante la codifica per offrire la flessibilità necessaria per gestire le modifiche al formato dell'archivio nelle versioni future.

Nella mia classe, ho aggiunto un metodo pratico per archiviare il mio oggetto:

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

e un altro per annullare l'archiviazione o creare un nuovo oggetto:

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

Poiché l'oggetto di livello superiore è un NSArray , dovrai modificare gli ultimi due metodi per il tuo caso, ma la maggior parte del codice del boilerplate sarà lo stesso.

Altri suggerimenti

Se vuoi recuperare un sottoinsieme degli oggetti, SQLite è di gran lunga la scelta migliore.

In caso contrario, è una scelta tra il formato plist e NSCoding. plist richiede di essere in grado di convertire i tuoi oggetti personalizzati in qualcosa di facile da usare e di riconvertire il plist nei tuoi oggetti, ma NSCoding è un po 'più difficile da avvolgere e non può essere facilmente modificato (o esaminato) a mano .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top