runtime-对成员变量操作应用之归档和返归档
为了实现归档和返归档,我们要让被归档对象的类接受NSCoding协议并且实现协议里的两个方法
- (void)encodeWithCoder:(NSCoder *)aCoder; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER
对上述两个方法的实现
- (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.name forKey:@"name"]; [aCoder encodeObject:self.age forKey:@"age"]; [aCoder encodeObject:self.gender forKey:@"gender"]; } - (id)initWithCoder:(NSCoder *)aDecoder { NSString *name = [aDecoder decodeObjectForKey:@"name"]; NSString *age = [aDecoder decodeObjectForKey:@"age"]; NSString *gender = [aDecoder decodeObjectForKey:@"gender"]; return [self initWithName:name age:age gender:gender]; }
这就是对一个类进行归档返归档的老方法。如果我们要进行的归档的类非常复杂有很多很多个成员变量(属性),那么上述这个老方法实现起来就很麻烦了,难道真的要一行一行的写重复代码吗?答案当然是NO了,runtime来解救你!相信大家对runtime操作成员变量的函数已经非常熟悉了(如果不熟悉请查看本人的上一篇博客),我们就是利用这些操作函数灵活的实现归档和解档。
下面用Person类举例子
.h文件中一些属性和成员变量的声明
{ NSString *clan; } @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger age; @property (nonatomic, strong) NSNumber *height; @property (nonatomic, copy) NSString *gender;
接收了NSCoding协议之后实现协议中的两个方法,没错,流程和以前的老方法是一样一样的
- (void)encodeWithCoder:(NSCoder *)aCoder { unsigned int count;// 所有成员变量的数量 Ivar *ivarList = class_copyIvarList([self class], &count);// 获取所有成员变量 for (int i = 0; i < count; i ++) { Ivar ivar = ivarList[i]; NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];// 获取成员变量的key值 [aCoder encodeObject:[self valueForKey:ivarName] forKey:ivarName];// 根据成员变量的key赋上对应的值 } } - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { if (self = [super init]) { unsigned int count; Ivar *ivarList = class_copyIvarList([self class], &count);// 获取所有成员变量 for (int i = 0; i < count; i ++) { Ivar ivar = ivarList[i]; NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)]; [self setValue:[aDecoder decodeObjectForKey:ivarName] forKey:ivarName]; } } return self; }
如果用runtime来实现归档和返归档遇到再复杂的类也不怕,可以利用循环来进行快速归档,不用逐一得写了