28

У меня есть словарь объектов; все они являются объектами POCO, которые должны быть сериализуемыми. Какую технику я должен искать для записи на диск. Я ищу простейший вариант для написания нескольких списков для сохранения состояния.Как сериализовать простой объект в iPhone sdk?

У меня есть 3 варианта.

  1. plist файлы. Однако это ограничивается только хранением предопределенных объектов (строк, чисел и т. Д.), А не объектов (например, человека с именем и возрастом).

  2. CoreData. (Новое в версии 3.0) Это будет хорошо работать; однако моя модель данных должна измениться, чтобы сделать эту работу. Это будет серьезная переделка, и я не уверен, стоит ли этого усилия.

  3. SQLLite. Внедрение простой базы данных SQL для чтения и из. Я сделал наименьшее количество ресурсов в этом, но я не хочу «переписывать» некоторые из основных функций ORM-данных.

ответ

14

Вы можете сделать это так же, как вы бы это сделать на Mac OS X: ваши POCO которые должны соответствовать протоколу NSCoding. См. here для концептуальной ссылки и here для ссылки NSCoding.

Если данные не настолько сумасшедшие, и у вас нет смехотворно сложных отношений между вашими объектами, выписывать все как plist, вероятно, ваш лучший вариант; это очень быстро выполнить и просто реализовать в вашем коде. Как вы сказали, CoreData, вероятно, будет lot дополнительной работы по адаптации вашего кода, и sqlite действительно хорош только для хранения данных, которые идеально подходят для хранения в реляционной базе данных. Имейте в виду, что sqlite также медленнее и использует больше ресурсов, чем работа с бинарными плитками.

33

Чтобы сериализовать пользовательский объект, вам просто нужно соответствовать протоколу NSCoding. Если ваш объект распространяется NSObject все, что вам нужно сделать (я считаю) является реализация этих (пример для человека объекта):

// Encode an object for an archive 
- (void)encodeWithCoder:(NSCoder *)coder 
{ 
    [super encodeWithCoder:coder]; 
    [coder encodeObject:name forKey:@“Name”]; 
    [coder encodeInteger:age forKey:@“Age”]; 
} 
// Decode an object from an archive 
- (id)initWithCoder:(NSCoder *)coder 
{ 
    self = [super initWithCoder:coder]; 
    name = [[coder decodeObjectForKey:@“Name”] retain]; 
    age = [coder decodeIntegerForKey:@“Age”]; 
} 

NSArrayNSDictionary и уже реализованы методы сериализации. Они будут сериализовать все объекты, которые они хранят (если объекты реализуют интерфейс NSCoder - они делают, если они расширяют NSObject). NSObject encodeWithCoder и initWithCoder ничего не делают по умолчанию, поэтому, если вы не реализуете свой собственный код в своих классах, ничего не сериализуется.

Если у вас есть NSArray или NSDictionary объектов вы можете синхронизировать их с помощью:

// Writing 
- (BOOL)writeToFile:(NSString *)aPath atomically:(BOOL)flag; 
- (BOOL)writeToURL:(NSURL *)aURL atomically:(BOOL)flag; 
// Reading 
- (id)initWithContentsOfFile:(NSString *)aPath; 
- (id)initWithContentsOfURL:(NSURL *)aURL; 
+0

имя является объектом типа NSString, так что вы хотите сохранить, если вы хотите использовать его, возраст только целые примитивные – stefanB

+0

Вы можете не используйте writeToFile, writeToURL, если объекты в NSArray не имеют тип NSString, NSData, NSArray или NSDictionary. Он всегда будет возвращать NO, если вы попытаетесь использовать эти методы в NSArray с любым другим типом объекта. – Snickers

+0

@Snickers вы говорите о NSArray, полном других типов объектов, которые все реализуют протокол NSCoding? Потому что это то, что я объяснил выше. В противном случае, не уверен, это ответ на 3 года, материал может измениться, пожалуйста, напишите свой ответ. Ppl будет повышать, если это лучшее решение. – stefanB