最近学习了归档与序列化的操作,在进行操作的时候需要为每一个类写上归档以及反归档相关的操作 但属性较多时这是一项费力不讨好的事情 遂自己写了个工具类,能够实现自动根据属性个数进行自动序列反序列化操作
主要运用了ios里runtime的方法与属性 其实在这里是和java的反射机制是一样的。
代码总共分为了两种
1.利用分类的方式实现 只需要拷贝分类进入工程 不需要进行其他任何操作 因为分类会对所有的model起作用 所以还有第二种方式供参考
2.需要将NSObject继承改为ZJAutoCoding继承
代码如下,恭敬敬上~~~
// // NSObject+ZJAutoCoding.h // // Created by Jason_Msbaby on 15/10/13. // Copyright ? 2015年 张杰. All rights reserved. // #import <Foundation/Foundation.h> @interface NSObject (ZJAutoCoding) @end // // NSObject+ZJAutoCoding.m // // Created by Jason_Msbaby on 15/10/13. // Copyright ? 2015年 张杰. All rights reserved. // #import "NSObject+ZJAutoCoding.h" #import <objc/runtime.h> @implementation NSObject (ZJAutoCoding) - (instancetype)initWithCoder:(NSCoder *)coder { //获取所有属性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList(self.class, &count); //遍历属性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; //当前属性对应的名 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; unsigned int c = 0; //获取所有特征 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍历所有特征 for (int j = 0; j < c; j++ ) { objc_property_attribute_t attr = attrs[j]; //这里的V指的是知道属性对应的成员变量的名称 例如name属性 在这里的特征值则为 V:_name 我们需要的是_name if (strcmp(attr.name, "V") == 0) { //然后我们需要获取实例进行赋值操作 Ivar ivar = class_getInstanceVariable(self.class, attr.value); object_setIvar(self, ivar,[coder decodeObjectForKey:proName]); } } free(attrs); } free(pros); return [self init]; } -(void)encodeWithCoder:(NSCoder *)aCoder{ //获取所有的属性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList([self class], &count); //遍历属性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; unsigned int c = 0; //获取实例变量的名称 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; //通过当前的属性 获取该属性的特征 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍历特征 能够得到其类型以及数值等内容 for (int j = 0; j < c; j++) { objc_property_attribute_t attr = attrs[j]; if (strcmp(attr.name, "V") == 0) {//如果是特征的名称 //获取当前类对应特征名称的实例变量 Ivar ivar = class_getInstanceVariable(self.class, attr.value); //得到该实例变量的数值 id object = object_getIvar(self, ivar); NSLog(@"%@",object); //归档 [aCoder encodeObject:object forKey:proName]; } } free(attrs); } free(pros); } @end -------------继承的方式如下------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ZJAutoCoding.h // // Created by Jason_Msbaby on 15/10/13. // Copyright ? 2015年 张杰. All rights reserved. // #import <Foundation/Foundation.h> /** 自动归档序列化 需要继承该类 - returns: */ @interface ZJAutoCoding : NSObject <NSCoding> /** * 全自动动态加载属性 实现反归档 * * @param coder * * @return */ - (instancetype)initWithCoder:(NSCoder *)coder; /** * 全自动动态加载属性 实现归档 * * @param aCoder */ -(void)encodeWithCoder:(NSCoder *)aCoder; @end // // ZJAutoCoding.m // UI高级2 // // Created by Jason_Msbaby on 15/10/13. // Copyright ? 2015年 张杰. All rights reserved. // #import "ZJAutoCoding.h" #import <objc/message.h> #import <objc/runtime.h> @implementation ZJAutoCoding - (instancetype)initWithCoder:(NSCoder *)coder { self = [super init]; if (self) { //获取所有属性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList(self.class, &count); //遍历属性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; //当前属性对应的名 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; unsigned int c = 0; //获取所有特征 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍历所有特征 for (int j = 0; j < c; j++ ) { objc_property_attribute_t attr = attrs[j]; //这里的V指的是知道属性对应的成员变量的名称 例如name属性 在这里的特征值则为 V:_name 我们需要的是_name if (strcmp(attr.name, "V") == 0) { //然后我们需要获取实例进行赋值操作 Ivar ivar = class_getInstanceVariable(self.class, attr.value); object_setIvar(self, ivar,[coder decodeObjectForKey:proName]); } } free(attrs); } free(pros); } return self; } -(void)encodeWithCoder:(NSCoder *)aCoder{ //获取所有的属性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList([self class], &count); //遍历属性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; unsigned int c = 0; //获取实例变量的名称 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; //通过当前的属性 获取该属性的特征 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍历特征 能够得到其类型以及数值等内容 for (int j = 0; j < c; j++) { objc_property_attribute_t attr = attrs[j]; if (strcmp(attr.name, "V") == 0) {//如果是特征的名称 //获取当前类对应特征名称的实例变量 Ivar ivar = class_getInstanceVariable(self.class, attr.value); //得到该实例变量的数值 id object = object_getIvar(self, ivar); NSLog(@"%@",object); //归档 [aCoder encodeObject:object forKey:proName]; } } free(attrs); } free(pros); } @end
自动解析复杂类的属性 实现归档或者进行序列化 反序列话的时候为每一个属性添加序列化方法的繁琐
原文:http://my.oschina.net/zhangjie9142/blog/516796