您的位置:首页 > 其它

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

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

主要运用了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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: