自动解析复杂类的属性 实现归档或者进行序列化 反序列话的时候为每一个属性添加序列化方法的繁琐
最近学习了归档与序列化的操作,在进行操作的时候需要为每一个类写上归档以及反归档相关的操作 但属性较多时这是一项费力不讨好的事情 遂自己写了个工具类,能够实现自动根据属性个数进行自动序列反序列化操作
主要运用了ios里runtime的方法与属性 其实在这里是和java的反射机制是一样的。
代码总共分为了两种
1.利用分类的方式实现 只需要拷贝分类进入工程 不需要进行其他任何操作 因为分类会对所有的model起作用 所以还有第二种方式供参考
2.需要将NSObject继承改为ZJAutoCoding继承
代码如下,恭敬敬上~~~
1 // 2 // NSObject+ZJAutoCoding.h 3 // 4 // Created by Jason_Msbaby on 15/10/13. 5 // Copyright © 2015年 张杰. All rights reserved. 6 // 7 8 #import <Foundation/Foundation.h> 9 10 @interface NSObject (ZJAutoCoding) 11 12 @end 13 14 15 16 17 18 19 // 20 // NSObject+ZJAutoCoding.m 21 // 22 // Created by Jason_Msbaby on 15/10/13. 23 // Copyright © 2015年 张杰. All rights reserved. 24 // 25 26 #import "NSObject+ZJAutoCoding.h" 27 #import <objc/runtime.h> 28 @implementation NSObject (ZJAutoCoding) 29 30 31 - (instancetype)initWithCoder:(NSCoder *)coder 32 { 33 //获取所有属性 34 unsigned int count = 0; 35 objc_property_t *pros = class_copyPropertyList(self.class, &count); 36 //遍历属性 37 for (int i = 0; i < count; i++) { 38 objc_property_t pro = pros[i]; 39 //当前属性对应的名 40 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; 41 unsigned int c = 0; 42 //获取所有特征 43 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); 44 //遍历所有特征 45 for (int j = 0; j < c; j++ ) { 46 objc_property_attribute_t attr = attrs[j]; 47 //这里的V指的是知道属性对应的成员变量的名称 例如name属性 在这里的特征值则为 V:_name 我们需要的是_name 48 if (strcmp(attr.name, "V") == 0) { 49 //然后我们需要获取实例进行赋值操作 50 Ivar ivar = class_getInstanceVariable(self.class, attr.value); 51 object_setIvar(self, ivar,[coder decodeObjectForKey:proName]); 52 } 53 } 54 free(attrs); 55 } 56 free(pros); 57 return [self init]; 58 } 59 60 -(void)encodeWithCoder:(NSCoder *)aCoder{ 61 //获取所有的属性 62 unsigned int count = 0; 63 objc_property_t *pros = class_copyPropertyList([self class], &count); 64 //遍历属性 65 for (int i = 0; i < count; i++) { 66 objc_property_t pro = pros[i]; 67 unsigned int c = 0; 68 //获取实例变量的名称 69 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; 70 //通过当前的属性 获取该属性的特征 71 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); 72 //遍历特征 能够得到其类型以及数值等内容 73 for (int j = 0; j < c; j++) { 74 objc_property_attribute_t attr = attrs[j]; 75 if (strcmp(attr.name, "V") == 0) {//如果是特征的名称 76 //获取当前类对应特征名称的实例变量 77 Ivar ivar = class_getInstanceVariable(self.class, attr.value); 78 //得到该实例变量的数值 79 id object = object_getIvar(self, ivar); 80 NSLog(@"%@",object); 81 //归档 82 [aCoder encodeObject:object forKey:proName]; 83 } 84 85 } 86 free(attrs); 87 } 88 free(pros); 89 } 90 91 @end 92 93 94 -------------继承的方式如下------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 95 96 97 // 98 // ZJAutoCoding.h 99 // 100 // Created by Jason_Msbaby on 15/10/13. 101 // Copyright © 2015年 张杰. All rights reserved. 102 // 103 104 #import <Foundation/Foundation.h> 105 106 /** 107 自动归档序列化 108 需要继承该类 109 110 - returns: 111 */ 112 @interface ZJAutoCoding : NSObject <NSCoding> 113 114 /** 115 * 全自动动态加载属性 实现反归档 116 * 117 * @param coder 118 * 119 * @return 120 */ 121 - (instancetype)initWithCoder:(NSCoder *)coder; 122 /** 123 * 全自动动态加载属性 实现归档 124 * 125 * @param aCoder 126 */ 127 -(void)encodeWithCoder:(NSCoder *)aCoder; 128 @end 129 130 131 132 133 134 // 135 // ZJAutoCoding.m 136 // UI高级2 137 // 138 // Created by Jason_Msbaby on 15/10/13. 139 // Copyright © 2015年 张杰. All rights reserved. 140 // 141 142 #import "ZJAutoCoding.h" 143 #import <objc/message.h> 144 #import <objc/runtime.h> 145 146 @implementation ZJAutoCoding 147 148 149 - (instancetype)initWithCoder:(NSCoder *)coder 150 { 151 self = [super init]; 152 if (self) { 153 //获取所有属性 154 unsigned int count = 0; 155 objc_property_t *pros = class_copyPropertyList(self.class, &count); 156 //遍历属性 157 for (int i = 0; i < count; i++) { 158 objc_property_t pro = pros[i]; 159 //当前属性对应的名 160 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; 161 unsigned int c = 0; 162 //获取所有特征 163 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); 164 //遍历所有特征 165 for (int j = 0; j < c; j++ ) { 166 objc_property_attribute_t attr = attrs[j]; 167 //这里的V指的是知道属性对应的成员变量的名称 例如name属性 在这里的特征值则为 V:_name 我们需要的是_name 168 if (strcmp(attr.name, "V") == 0) { 169 //然后我们需要获取实例进行赋值操作 170 Ivar ivar = class_getInstanceVariable(self.class, attr.value); 171 object_setIvar(self, ivar,[coder decodeObjectForKey:proName]); 172 } 173 } 174 free(attrs); 175 } 176 free(pros); 177 178 } 179 return self; 180 } 181 182 -(void)encodeWithCoder:(NSCoder *)aCoder{ 183 //获取所有的属性 184 unsigned int count = 0; 185 objc_property_t *pros = class_copyPropertyList([self class], &count); 186 //遍历属性 187 for (int i = 0; i < count; i++) { 188 objc_property_t pro = pros[i]; 189 unsigned int c = 0; 190 //获取实例变量的名称 191 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; 192 //通过当前的属性 获取该属性的特征 193 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); 194 //遍历特征 能够得到其类型以及数值等内容 195 for (int j = 0; j < c; j++) { 196 objc_property_attribute_t attr = attrs[j]; 197 if (strcmp(attr.name, "V") == 0) {//如果是特征的名称 198 //获取当前类对应特征名称的实例变量 199 Ivar ivar = class_getInstanceVariable(self.class, attr.value); 200 //得到该实例变量的数值 201 id object = object_getIvar(self, ivar); 202 NSLog(@"%@",object); 203 //归档 204 [aCoder encodeObject:object forKey:proName]; 205 } 206 207 } 208 free(attrs); 209 } 210 free(pros); 211 } 212 213 @end