Подтвердить что ты не робот

Правильный способ сохранения/сериализации пользовательских объектов в iOS

У меня есть пользовательский объект, подкласс UIImageView, который содержит несколько объектов gestureRecognizer.

Если у меня есть несколько таких объектов, хранящихся в NSMutableArray, как этот массив объектов будет сохранен на диск, чтобы он мог быть загружен, когда пользователь снова запускает приложение?

Я хотел бы загрузить массив с диска и использовать объекты.

4b9b3361

Ответ 1

Моя реализация для чего-то подобного следующая и работает отлично:

Пользовательский объект (Настройки) должен реализовать протокол NSCoding:

-(void)encodeWithCoder:(NSCoder *)encoder{
    [encoder encodeObject:self.difficulty forKey:@"difficulty"];
    [encoder encodeObject:self.language forKey:@"language"];
    [encoder encodeObject:self.category forKey:@"category"];
    [encoder encodeObject:self.playerType forKey:@"playerType"];
}

- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.difficulty = [decoder decodeObjectForKey:@"difficulty"];
        self.language = [decoder decodeObjectForKey:@"language"];
        self.category = [decoder decodeObjectForKey:@"category"];
        self.playerType = [decoder decodeObjectForKey:@"playerType"];
    }
    return self;
}

Следующий код записывает пользовательский объект в файл (set.txt), а затем восстанавливает его в массив myArray:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"set.txt"];

NSMutableArray *myObject=[NSMutableArray array];
[myObject addObject:self.settings];    

[NSKeyedArchiver archiveRootObject:myObject toFile:appFile]; 

NSMutableArray* myArray = [NSKeyedUnarchiver unarchiveObjectWithFile:appFile]; 

Ответ 2

//store the array
[NSKeyedArchiver archiveRootObject:myArray toFile:@"someFile"];

//load the array
NSMutableArray* myArray = [NSKeyedUnarchiver unarchiveObjectWithFile:@"someFile"];

Официальные ссылки.

Обратите внимание, что когда массив содержит пользовательские типы объектов, вы должны убедиться, что ваш тип соответствует NSCoding Protocol, прежде чем это будет работать.

Ответ 3

В этом блоге объясняется, как хранить массив пользовательских объектов на диске с помощью NSKeyedArchiver и читать его с помощью NSKeyedUnarchiver:

http://www.cocoabuilder.com/archive/cocoa/240775-saving-nsarray-of-custom-objects.html

Apple также имеет очень полезное руководство по этому вопросу, Руководство по программированию и сериализации архивов.

Ответ 4

Я хотел бы поделиться своими улучшениями с решением Kostas, если кто-то нуждается в них.

  • Имя класса можно использовать для генерации имени текстового файла для хранения объекта.
  • Это хорошее решение для сохранения объектов контроллера вида в режиме viewWillDisappear и восстановления их в методе viewDidLoad.
  • Имя файла должно быть сгенерировано отдельным методом, чтобы избежать дублирования кода.
  • После восстановления объекта его следует проверить, чтобы он не был равен нулю.

- (void)viewDidLoad
{
  [super viewDidLoad];

  // Restoring form object from the file
  NSString *formFilePath = [self formFilePath];
  RRCreateResumeForm *form = [NSKeyedUnarchiver unarchiveObjectWithFile:formFilePath];
  if (form != nil) {
    self.formController.form = form;
  }
}


- (void)viewWillDisappear:(BOOL)animated
{
  [super viewWillDisappear:animated];

  // Saving the form object to the file
  NSString *formFilePath = [self formFilePath];
  [NSKeyedArchiver archiveRootObject:self.formController.form toFile:formFilePath];
}


// Returns a file path to the file with stored form data for form controller
- (NSString *)formFilePath
{
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentsDirectory = [paths objectAtIndex:0];
  NSString *formClassName = NSStringFromClass( [self.formController.form class] );
  NSString *formFileName = [NSString stringWithFormat:@"%@.txt", formClassName];
  NSString *formFilePath = [documentsDirectory stringByAppendingPathComponent:formFileName];

  return formFilePath;
}