NSuserDefaults保存Model

2019-05-25  本文已影响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

搞定收工

上一篇下一篇

猜你喜欢

热点阅读