工作中,Runtime实现对象的归档/解档的功能经常用到。之前没有做整理,今天特意整理了一下,也算作为一个知识点吧。方便自己的学习巩固。
其实,这个功能实现起来很简单。就下面几步:
第一步:创建类,遵守NSCoding协议
第二步:实现NSCoding协议中的两个方法
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;
第三步:利用NSKeyedArchiver归档/NSKeyedUnarchiver解档
接下来,我就新建一个类CustomClass,随便添加几个属性,来利用以上步骤实现该功能。
#import <Foundation/Foundation.h>
@interface CustomClass : NSObject<NSCoding>
//随便添加了几个属性
@property(nonatomic,copy)NSString *attribute1;
@property(nonatomic,copy)NSString *attribute2;
@property(nonatomic,assign)NSInteger attribute3;
@property(nonatomic,assign)BOOL attribute4;
@end
CustomClass.m中的实现代码:
#import "CustomClass.h"
#import <objc/runtime.h>
@implementation CustomClass
//归档
- (void)encodeWithCoder:(NSCoder *)aCoder{
unsigned int count = 0;
//取到所有的Ivar
Ivar *ivars = class_copyIvarList([self class], &count);
//遍历 逐个属性归档
for (int i = 0; i < count; i++) {
//找到Ivar
Ivar ivar = ivars[i];
//找到Ivar对应的名称
const char *name = ivar_getName(ivar);
//找到key
NSString *key = [NSString stringWithUTF8String:name];
//key对应的value值
id value = [self valueForKey:key];
//键值保存
[aCoder encodeObject:value forKey:key];
}
free(ivars);
}
//解档
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([self class], &count);
for (int i = 0; i < count; i++) {
//拿到每一个Ivar 在这里拿到的是数组的首地址
Ivar ivar = ivars[i];
//ivar对应的名称
const char *name = ivar_getName(ivar);
//属性key
NSString *key = [NSString stringWithUTF8String:name];
//属性value
id value = [aDecoder decodeObjectForKey:key];
//KVC 将值设置到对应的属性上面
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}
@end
接下来就是具体的应用:
存
CustomClass *model = [[CustomClass alloc]init];
model.attribute1 = @"刘高见";
model.attribute2 = @"我是谁";
model.attribute3 = 20;
model.attribute4 = YES;
//路径
NSString *path = NSTemporaryDirectory();
NSString *filePath = [path stringByAppendingString:@"liugaojian.file"];
//归档
[NSKeyedArchiver archiveRootObject:model toFile:filePath];
//取
//路径
NSString *path = NSTemporaryDirectory();
NSString *filePath = [path stringByAppendingString:@"liugaojian.file"];
//归档
CustomClass *model = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"attribute1=%@-------attribute2=%@-------attribute3=%ld--------attribute4=%d",model.attribute1,model.attribute2,(long)model.attribute3,model.attribute4);
哈哈 over~~~