Лучший способ сохранить в nsuserdefaults для пользовательского класса? - PullRequest
16 голосов
/ 08 июня 2010

Если у меня есть пользовательский класс Person, который имеет три переменные (которые являются собственностью и синтезированы):

NSString* theName;
float* theHeight;
int theAge;

Экземпляры Person хранятся в NSArray 'Group'. Есть только одна группа. Каков наилучший способ хранения и загрузки группы в NSUserDefaults? (имея в виду, что float и int недопустимы для NSUserDefaults)

Ответы [ 2 ]

45 голосов
/ 31 января 2013

@ Ответ Брэда Смита не является полным и даже в некотором смысле неверным. Мы должны использовать NSKeyedArchiver и NSKeyedUnarchiver следующим образом:

Сделайте ваш класс (например, в данном случае Person) соответствующим протоколу NSCoding и реализуйте оба метода следующим образом:

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if(self) {
        self.name = [decoder decodeObjectForKey:<key_for_property_name>];
        // as height is a pointer
        *self.height = [decoder decodeFloatForKey:<key_for_property_height>];
        self.age = [decoder decodeIntForKey:<key_for_property_age>];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:<key_for_property_name>];
    //as height is a pointer
    [encoder encodeFloat:*self.height forKey:<key_for_property_height>]
    [encoder encodeInt:self.age forKey:<key_for_property_age>];
}

Использование NSUserDefaults

// Write to NSUserDefaults
NSData *archivedObject = [NSKeyedArchiver archivedDataWithRootObject:<your_class_object>];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:archivedObject forKey:<key_for_archived_object>];
[defaults synchronize];

// Read from NSUserDefaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *archivedObject = [defaults objectForKey:<key_for_archived_object>];
<your_class> *obj = (<your_class> *)[NSKeyedUnarchiver unarchiveObjectWithData:archivedObject];
1 голос
/ 04 июля 2013

Я считаю реализацию encodeWithCoder и initWithCoder довольно скучной, особенно если у вас много атрибутов в вашем классе и много классов для сохранения в NSUserDefaults.

Я создаю библиотеку RMMapper (https://github.com/roomorama/RMMapper), чтобы помочьпроще и удобнее сохранять пользовательский объект в NSUserDefaults.

Чтобы пометить класс как архивируемый, просто используйте: #import "NSObject+RMArchivable.h"

Чтобы сохранить пользовательский объект в NSUserDefaults:

#import "NSUserDefaults+RMSaveCustomObject.h"

NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults rm_setCustomObject:user forKey:@"SAVED_DATA"];

Чтобы получить пользовательский объект из NSUserDefaults:

user = [defaults rm_customObjectForKey:@"SAVED_DATA"]; 
...