NSUserDefault 存储自定义对象

NSUserDefault 存储自定义对象

NSUserDefault 只可以存储 int、bool 等基本数据类型,或者 NSString 、NSArray等 复合类型。但是,如果一个自定义的对象的话,那该怎样使用呢?

在 所写的类 中,需要实现两个协议:NSCoping、NSCoding。
这两个协议主要实现的方法是:

  • NSCoding

    `- (instancetype)initWithCoder:(NSCoder *)aDecoder
    
    `- (void)encodeWithCoder:(NSCoder *)aCoder`
    
  • NSCoping

    `- (id)copyWithZone:(NSZone *)zone
        

    eg:

@interface Chinese ()<NSCoding, NSCopying>

@end

@implementation Chinese



`- (instancetype)initWithProvince:(NSString *)province height:(NSInteger)height isMale:(BOOL)isMale {
        self = [super init];
        if (self) {
            _province = province;
            _height = height;
            _isMale = isMale;
        }
        
        return self;
    }



`- (void)encodeWithCoder:(NSCoder *)aCoder {
        [aCoder encodeObject:self.province forKey:@"province"];
        [aCoder encodeInteger:self.height forKey:@"height"];
        [aCoder encodeBool:self.isMale forKey:@"isMale"];
    }
    
\- (instancetype)initWithCoder:(NSCoder *)aDecoder {
        self = [super init];
        if (self) {
            self.province = [aDecoder decodeObjectForKey:@"province"];
            self.height = [aDecoder decodeIntegerForKey:@"height"];
            self.isMale = [aDecoder decodeBoolForKey:@"isMale"];
        }
        return self;
    }
    
`- (id)copyWithZone:(NSZone *)zone {
        Chinese *copyChinese = [[self class] allocWithZone:zone];
        copyChinese.province = [self.province copyWithZone:zone];
        copyChinese.isMale = self.isMale;
        copyChinese.height = self.height;
        return copyChinese;
    }

类似这样的形式,自定义的一个类。

在使用上呢,则需要先对 该对象 进行 归档,即 archive。

eg:



Chinese *cantonese = [[Chinese alloc] initWithProvince:@"广东" height:180 isMale:YES];
NSData *chineseDate = [NSKeyedArchiver archivedDataWithRootObject:cantonese];
[[NSUserDefaults standardUserDefaults] setObject:chineseDate forKey:@"chinese"];
        
        

这是由于 本地化存储 的特性导致的。所以需要先归档成 NSData类型,在对其进行存储。因此,在取出数据的时候,得到的是 NSData数据类型,再对其进行解档 得到相对应的对象。eg:

NSData *chineseData = [[NSUserDefaults standardUserDefaults] objectForKey:@"chinese"];
Chinese *chinese = [NSKeyedUnarchiver unarchiveObjectWithData:chineseData];

基本流程,差不多就是这样。

那如果 自定义对象 的 一个属性 也是 自定义对象的话,比如:

@interface Person : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) Chinese *chinese;

@end

那么在实现 NSCodingNSCoping两个协议时,则

`- (instancetype)initWithCoder:(NSCoder *)aDecoder {
        self = [super init];
        if (self) {
            self.name = [aDecoder decodeObjectForKey:@"name"];
            self.chinese = [aDecoder decodeObjectOfClass:[Chinese class] forKey:@"chinese"];
        }
        
        return self;
    }
    
`- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.chinese forKey:@"chinese"];
}
    
    
`- (id)copyWithZone:(NSZone *)zone {
    Person *copyPerson = [[self class] allocWithZone:zone];
    copyPerson.name = [self.name copyWithZone:zone];
    copyPerson.chinese = [self.chinese copyWithZone:zone];    
    return copyPerson;
}

小小拙见,有错请指出。谢谢!

    原文作者:六叔
    原文地址: https://segmentfault.com/a/1190000004361046
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞