NSCoding
farà esattamente quello che desideri. Vi consiglio di leggere su di esso nei documenti Apple, ma ho pensato che fosse abbastanza semplice da usare. La classe (e le eventuali classi secondarie) dovranno implementare il protocollo NSCoding
e sarà necessario aggiungere i metodi -encodeWithCoder:
e -initWithCoder:
ai propri oggetti. La maggior parte delle classi di framework comuni implementano già NSCoding
.
Il codice per la 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 di dare flessibilità per gestire le modifiche al formato di archivio in versioni future.
Nella mia classe, ho aggiunto un metodo comodo 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 decomprimere o di 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;
}
Dal momento che l'oggetto di livello superiore è un NSArray
, dovrai modificare gli ultimi due metodi per il tuo caso, ma la maggior parte del codice boilerplate sarà lo stesso.
fonte
2009-03-15 19:58:42
E quello produrrebbe un bel plist? Avevo l'impressione che scrivere NSData producesse solo dati serializzati e non un plist. – Jasarien
Questo produce un archivio NSCoding, un file con copie conservate degli oggetti, un po 'come un file pennino (ma non è possibile utilizzare Interface Builder per modificarlo). La "Guida alla programmazione di archivi e serializzazioni per il cacao" nella documentazione lo spiegherà. –
Per impostazione predefinita archivia in un plist binario, ma è possibile modificarlo in un plist xml se lo si desidera. Sfortunatamente non è veramente leggibile perché contiene metadati di classe e puntatore e anche i dati dell'oggetto. –