Runtime应用三《对自定义模型归档解档》

本文探讨了在自定义模型中使用归档和解档的方法,对比了常规方法与版本号记录法,后者能更优雅地处理字段更新,确保数据一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NSUserDefaults只能存储基本的数据类型,对于自定义的模型无法进行数据存储。这时候就要用到了归档和解档

方法一:

最常规的用法是在自定义模型中实现两个方法encodeWithCoder和initWithCoder

- (void)encodeWithCoder:(NSCoder *)aCoder {     [aCoder encodeObject :self.storeName   forKey:@"storeName"];     [aCoder encodeInteger:self.storeAge    forKey:@"storeAge"]; }  - (instancetype)initWithCoder:(NSCoder *)aDecoder {     self = [super init];     if (self) {         self.storeName = [aDecoder decodeObjectForKey:@"storeName"];         self.storeAge  = [aDecoder decodeIntForKey:@"storeAge"];     }     return self; }
方法一

使用常规用法有个缺点就是如果新增字段,就要继续在两个方法里面一直的添加属性的归档和解档,比较麻烦。所有就有了方法二

方法二:

- (instancetype)initWithCoder:(NSCoder *)aDecoder {     unsigned int iVarCount = 0;     Ivar         *iVarList = class_copyIvarList([self class], &iVarCount);     for (unsigned int i = 0; i < iVarCount; i++) {         Ivar ivar            = *(iVarList + i);         const char *ivarName = ivar_getName(ivar);         NSString   *key      = [NSString stringWithUTF8String:ivarName];         id          varValue = [aDecoder decodeObjectForKey:key];         if (varValue) {             [self setValue:varValue forKey:key];         }     }     free(iVarList);     return self; }  - (void)encodeWithCoder:(NSCoder *)aCoder {     unsigned int iVarCount = 0;     Ivar         *iVarList = class_copyIvarList([self class], &iVarCount);     for (unsigned int i = 0; i < iVarCount; i++) {         Ivar        ivar      = *(iVarList + i);         const char  *ivarName = ivar_getName(ivar);         NSString    *key      = [NSString stringWithUTF8String:ivarName];         id          varValue  = [self valueForKey:key];         if (varValue) {             [aCoder encodeObject:varValue forKey:key];         }     }     free(iVarList); }
方法二

测试一下最终结果:

static NSString *const kLREncodeDataArrayKey = @"kLREncodeDataArrayKey";

- (void)test4 {     //     NSString *arrayKey = [NSString stringWithFormat:@"%@_%@",kLREncodeDataArrayKey,@"1.0"];     NSData   *data             = [[NSUserDefaults standardUserDefaults] objectForKey:arrayKey];     NSMutableArray *storeArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];     if (storeArray.count > 0) {         [self showTest4Result:storeArray];     }          NSMutableArray *array = [NSMutableArray array];     LREncodeModel *model  = ({         LREncodeModel *model  = [LREncodeModel new];         model.storeName       = @"小仙女";         model.storeAge        = 18;         model;     });     [array addObject:model];          model  = ({         LREncodeModel *model  = [LREncodeModel new];         model.storeName       = @"哪吒";         model.storeAge        = 3;         model;     });     [array addObject:model];          model  = ({         LREncodeModel *model  = [LREncodeModel new];         model.storeName       = @"太上老君";         model.storeAge        = 999;         model;     });     [array addObject:model];          [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:array.copy] forKey:arrayKey];     [[NSUserDefaults standardUserDefaults] synchronize]; }
创建模型并归档
- (void)showTest4Result:(NSMutableArray *)storeArray {     __block NSString *str = @"";     [storeArray enumerateObjectsUsingBlock:^(LREncodeModel *  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {         NSLog(@"storeAge---%ld---storeName:%@",(long)obj.storeAge,obj.storeName);         str = [str stringByAppendingString:[NSString stringWithFormat:@"storeAge:%ld--storeName:%@\n",(long)obj.storeAge,obj.storeName]];     }];          UILabel *label = ({         UILabel *label      = [UILabel new];         label.frame         = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width - 20 * 2, [UIScreen mainScreen].bounds.size.height - 20 * 2);         label.text          = str;         label.numberOfLines = 0;         label;     });     [self.view addSubview:label]; }
解档绘制数据
模拟器显示

我这边只是做了一个demo进行测试。你可以在自定义模型中记录一个版本号。版本号存储的是API返回的上一次的版本号。在请求到API数据以后,看解档的本地版本号和API饭回的版本号是否一致,一致就直接绘制数据,如果不一致,先更新本地版本号为API返回的版本号,然后重新进行归档数据显示。以上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值