Question

J'ai un objet personnalisé qui hérite simplement de NSObject. Il a 3 membres - deux floats et un NSDate .

Mon application va créer un tableau contenant plusieurs objets et je dois le persister entre les exécutions. Comment puis-je accomplir cela?

J'ai envisagé d'utiliser une base de données SQLite, mais je pense que c'est un peu excessif, car la seule requête que je ferais jamais serait select * .

Dans un monde idéal, j'aimerais utiliser un fichier plist xml. Je ne suis toutefois pas sûr de pouvoir le faire avec mon objet personnalisé. Je sais qu'il existe un ensemble d'objets Property List et que NSArray correspond à celui-ci, mais writeToFile: atomically: ne fonctionne qu'avec les objets de liste de propriétés.

Toute pensée serait appréciée, merci!

Était-ce utile?

La solution

NSCoding fera exactement ce que vous voulez. Je vous recommande de le lire dans la documentation Apple, mais j’ai pensé que c’était assez simple à utiliser. Votre classe (et toutes les classes enfants) devront implémenter le protocole NSCoding et vous devrez ajouter -encodeWithCoder: et -initWithCoder: . méthodes à vos objets. La plupart des classes d'infrastructure courantes implémentent déjà le NSCoding .

Le code de votre classe ressemblera à ceci:

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

Il est recommandé d'ajouter un numéro de version lors de l'encodage pour vous permettre de gérer les modifications apportées au format de votre archive dans les versions futures.

Dans ma classe, j'ai ajouté une méthode pratique pour archiver mon objet:

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

et un autre pour désarchiver ou créer un nouvel objet:

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

Étant donné que votre objet de niveau supérieur est un NSArray , vous devrez modifier les deux dernières méthodes pour votre cas, mais la plupart du code standard sera le même.

Autres conseils

Si vous souhaitez récupérer un sous-ensemble des objets, SQLite est de loin votre meilleur choix.

Sinon, vous avez le choix entre le format de liste d'adresses et le format NSCoding. Plist exige que vous soyez capable de convertir vos objets personnalisés en quelque chose de pliable, puis de reconvertir le plist en objets, mais le NSCoding est un peu plus difficile à comprendre et ne peut pas être facilement édité (ou examiné) à la main. .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top