Best way to save to nsuserdefaults for custom clas

2019-01-17 04:46发布

问题:

If I have a custom class Person which has three variables (which are propertized and synthesized):

NSString* theName;
float* theHeight;
int theAge;

Person instances are stored in an NSArray 'Group'. There is only one Group. What is the best way of storing and loading the Group in NSUserDefaults? (bearing in mind that float and int are not legal for NSUserDefaults)

回答1:

@Brad Smith's answer is not complete, and even is incorrect in some sense. We have to use NSKeyedArchiver and NSKeyedUnarchiver as follows:

Make your class (for example in this case Person) to conform to protocol NSCoding and implement both the methods as:

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

Using 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];


回答2:

I find implementing encodeWithCoder and initWithCoder quite boring, especially if you have many attributes in your class, and many classes to save to NSUserDefaults.

I create a library RMMapper (https://github.com/roomorama/RMMapper) to help save custom object into NSUserDefaults easier and more convenient.

To mark a class as archivable, just use: #import "NSObject+RMArchivable.h"

To save a custom object into NSUserDefaults:

#import "NSUserDefaults+RMSaveCustomObject.h"

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

To get custom obj from NSUserDefaults:

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