美文网首页
NSuserDefaults保存Model

NSuserDefaults保存Model

作者: 流小星 | 来源:发表于2019-05-25 16:47 被阅读0次

    NSuserDefaults是我们在iOS中保存一些基本信息的常用手段,NSuserDefaults默认能保存NSData,NSDictionary,NSArray,NSString,NSNumber,BOOL这些数据类型。但有时候我们会需要保存一个自定义的Model,怎么做呢?
    我们先来试一下,把model直接存入NSuserDefaults中

    //这是model
    @interface AccountModel : NSObject
    @property (nonatomic ,copy) NSString * age;
    @property (nonatomic ,copy) NSString * username;
    @end
    
    @implementation AccountModel
    @end
    
    AccountModel *model = [[AccountModel alloc]init];
    model.age = @"18";
    model.username = @"2333";
    [[NSUserDefaults standardUserDefaults]setObject:model forKey:@"model"];
    

    接下来run一下,闪退了。。。看一下闪退原因

    [User Defaults] Attempt to set a non-property-list object < AccountModel: 0x600002426280> as an NSUserDefaults/CFPreferences value for key model

    [User Defaults]尝试将非属性列表对象<AccountModel:0x600002426280>设置为关键模型的NSUserDefaults / CFPreferences值,说明不支持model直接存入,那我们转换成NSData试一下

    AccountModel *model = [[AccountModel alloc]init];
    model.age = @"18";
    model.username = @"2333";
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:model];
    [[NSUserDefaults standardUserDefaults]setObject:data forKey:@"model"];
    

    又双闪退了。。。

    -[AccountModel encodeWithCoder:]: unrecognized selector sent to instance 0x600001990cc0

    说的是没有实现该encodeWithCoder方法,这就需要我们实现NSCoding协议,话不多说,无非打打杀杀,哦不,无非写写代码

    @interface AccountModel : NSObject<NSCoding>
    @property (nonatomic ,copy) NSString * age;
    @property (nonatomic ,copy) NSString * username;
    @end
    @implementation AccountModel
    
    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:self.age forKey:@"age"];
        [aCoder encodeObject:self.username forKey:@"username"];
    }
    - (instancetype)initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super init]) {
            self.age = [aDecoder decodeObjectForKey:@"age"];
            self.username = [aDecoder decodeObjectForKey:@"username"];
        }
        return self;
    }
    
    @end
    

    运行一下,OK了,model正常存放在NSuserDefaults中了,但是假如100个字符串,我们要实现100个字符串的NSCoding协议?那不太优雅,我们用runtime搞一下,话不多说,上代码

    @implementation AccountModel
    
    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
        unsigned  int count = 0;
        Ivar *ivars = class_copyIvarList(self.class, &count);
        for (int i = 0; i < count; i++) {
            const char *cname = ivar_getName(ivars[i]);
            NSString *name = [NSString stringWithUTF8String:cname];
            NSString *key = [name substringFromIndex:1];
            id value = [self valueForKey:key];
            [aCoder encodeObject:value forKey:key];
        }
    }
    - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super init]) {
            unsigned  int count = 0;
            Ivar *ivars = class_copyIvarList(self.class, &count);
            for (int i = 0; i < count; i++) {
                const char *cname = ivar_getName(ivars[i]);
                NSString *name = [NSString stringWithUTF8String:cname];
                NSString *key = [name substringFromIndex:1];
                id value = [aDecoder decodeObjectForKey:key];
                [self setValue:value forKey:key];
            }
        }
        return self;
    }
    
    @end
    
    

    搞定收工

    相关文章

      网友评论

          本文标题:NSuserDefaults保存Model

          本文链接:https://www.haomeiwen.com/subject/nxkazqtx.html