Frage

Ich habe ein benutzerdefiniertes Objekt, das einfach von NSObject erbt. Es verfügt über 3 Mitglieder -. Zwei Schwimmer und ein NSDate

Meine app wird ein Array mit einer Anzahl dieser Objekte haben, herum zu treten, und ich brauche es zwischen den Läufen zu bestehen. Wie kann ich das erreichen?

Ich habe daran gedacht, einen SQLite db verwenden, aber ich denke, dass es ein bisschen übertrieben, da die einzige Abfrage würde ich jemals select * würde tun.

In einer idealen Welt würde Ich mag eine XML-plist-Datei verwenden. Ich bin mir nicht sicher, ob ich aber mit meinem benutzerdefinierten Objekt tun kann. Ich weiß, es gibt eine Reihe von Eigenschaftenliste Objekten, und das NSArray kommt unter dem, aber writeToFile:atomically: funktioniert nur mit Eigenschaftsliste Objekten.

Alle Gedanken würden geschätzt, Dank!

War es hilfreich?

Lösung

NSCoding wird genau das tun, was Sie wollen. Ich empfehle Ihnen, auf sie in der Apple-Dokumente lesen, aber ich dachte, es war ziemlich einfach zu bedienen. Ihre Klasse (und alle untergeordneten Klassen) müssen die NSCoding Protokoll implementieren und Sie müssen -encodeWithCoder: und -initWithCoder: Methoden, um Ihre Objekte hinzuzufügen. Die meisten der gemeinsamen Rahmens Klassen implementieren NSCoding bereits.

Der Code für Ihre Klasse wird wie folgt aussehen:

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

Es wird empfohlen, dass Sie eine Versionsnummer hinzufügen beim Encodieren Ihnen Flexibilität zu geben, Änderungen an Ihrem Archiv-Format in zukünftigen Versionen zu verwalten.

In meiner Klasse, habe ich eine bequeme Methode, meine Aufgabe zu archivieren:

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

und ein anderer aus dem Archiv entfernen oder um ein neues Objekt zu erstellen:

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

Da Ihr Top-Level-Objekt ist ein NSArray, werden Sie die letzten beiden Methoden für Ihren Fall ändern müssen, aber die meisten der Standardcode wird die gleiche sein.

Andere Tipps

Wenn Sie eine Teilmenge der Objekte zu wollen gehen abzuzurufen, SQLite ist bei weitem der beste Wahl.

Wenn nicht, ist es eine Wahl zwischen plist Format und NSCoding. plist erfordert, dass Sie Ihre benutzerdefinierten Objekte in etwas plist freundlich in der Lage sein zu konvertieren und dann in Ihre Objekte die plist konvertieren zurück, aber NSCoding ist ein wenig schwieriger, den Kopf herum zu wickeln und nicht leicht bearbeitet werden kann (oder geprüft) von Hand .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top