2009-03-15 8 views
10

У меня есть пользовательский объект, который просто наследуется от NSObject. Он имеет 3 члена - два поплавка и NSDate.Сохраняющиеся пользовательские объекты

Мое приложение будет иметь массив с рядом этих объектов, ногами, и мне нужно сохранить его между прогонами. Как я могу это сделать?

Я думал об использовании SQLite db, но я думаю, что это немного перебор, так как единственный запрос, который я когда-либо делал, будет select *.

В идеальном мире, я хотел бы использовать файл xml plist. Я не уверен, могу ли я сделать это с помощью своего пользовательского объекта. Я знаю, что есть набор объектов Property List, и что NSArray подпадает под это, но writeToFile:atomically: работает только с объектами списка свойств.

Любые мысли будут оценены, спасибо!

ответ

21

NSCoding будет делать именно то, что вы хотите. Я рекомендую вам прочитать его в документах Apple, но я подумал, что это довольно просто использовать. Ваш класс (и любые дочерние классы) должен будет реализовать протокол NSCoding, и вам нужно будет добавить методы -encodeWithCoder: и -initWithCoder:. Большинство общих классов классов уже реализуют NSCoding.

Код для вашего класса будет выглядеть примерно так:

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

Это рекомендуется добавить номер версии при кодировании, чтобы дать вам возможность управлять изменения в формат архива в будущих версиях.

В моем классе, я добавил удобный метод для архивирования моего объекта:

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

и еще один разархивировать или создать новый объект:

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

Поскольку ваш верхний объект уровня является NSArray, вам нужно будет изменить два последних метода для вашего случая, но большая часть кода шаблона будет одинаковой.

+0

И это создаст приятный plist? У меня создалось впечатление, что запись NSData будет просто создавать сериализованные данные, а не plist. – Jasarien

+0

Это создает архив NSCoding - файл с сохраненными копиями ваших объектов, вроде файла nib (но вы не можете использовать Interface Builder для его редактирования). Объясните это в «Руководстве по программированию и сериализации программ для какао» в вашей документации. –

+0

По умолчанию он архивирует двоичный диск, но вы можете изменить его на xml plist, если хотите. К сожалению, на самом деле он не читается человеком, поскольку содержит метаданные класса и указателя, а также данные объекта. –

0

Если вы хотите получить подмножество объектов, SQLite - это, безусловно, ваш лучший выбор.

Если нет, это выбор между форматом plist и NSCoding. plist требует, чтобы вы могли конвертировать ваши пользовательские объекты в нечто дружелюбное к plist, а затем преобразовывать plist обратно в ваши объекты, но NSCoding немного сложнее обернуть вокруг вас и не может быть легко отредактирован (или проверен) вручную ,

+0

Я не буду использовать подмножества. Мне просто нужен полный список. Как можно было бы конвертировать объект в дружественный к plist? Я понял, что существует набор объектов Property List, и это все. Моя цель не состоит в том, что не является пластичным ... – Jasarien

 Смежные вопросы

  • Нет связанных вопросов^_^