自动解析复杂类的属性 实现归档或者进行序列化 反序列话的时候为每一个属性添加序列化方法的繁琐

最近学习了归档与序列化的操作,在进行操作的时候需要为每一个类写上归档以及反归档相关的操作  但属性较多时这是一项费力不讨好的事情  遂自己写了个工具类,能够实现自动根据属性个数进行自动序列反序列化操作

主要运用了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

 

posted @ 2015-10-17 16:06  Jason_Msbaby  阅读(167)  评论(0编辑  收藏  举报