今天在cocoachina中看到《利用runtime实现自定义对象归档》,so 自己捣鼓了一下,记录如下:
在前面的博客中,已经记录过自定义对象归档,详情请参照之前的博客:http://blog.csdn.net/xiaonaiping061/article/details/47952077。之前博客中讲解的自定义对象归档适用于对象属性较少的情况,但是面对属性比较多的情况,就需要在解档和归档函数中写很多的代码。为了解决这个问题runtime实现自定义对象归档就派上用场了。
干货如下:
1、创建student类,并遵守NScoding协议
2、.m文件中导入runtime头文件:#import"objc/runtime.h"
此处说明一下三点:
1、getter 和 setter方法的格式:
getter方法:
- (NSString *)name{
return @"张三";
}
setter方法:
- (void)setName:(NSString *)name{}
2、NSSelectorFromString(...)通过方法名转化为方法
SEL getSel =NSSelectorFromString(perperName);
3、动态获取对象的属性列表
/**
* Ivar 属性成员
* @param Class 当前对象的类
* @param outCount 无符号整型的变量指针,存储属性的个数
* @return IvarList属性数组
*/
OBJC_EXPORTIvar *class_copyIvarList(Class cls, unsigned int *outCount)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
/**
* 返回一个实例变量的名字.
*
* @param v 实例变量.
*
* @return A c类型的字符串 变量名.
*/
OBJC_EXPORTconst char *ivar_getName(Ivar v)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
3、具体实现
/**
* 获取成员属性数组
*
* @return 数组
*/
+ (NSArray *)propertyOfSelf
{
unsigned int count;
Ivar *ivarList = class_copyIvarList(self, &count);
NSMutableArray *properName = [NSMutableArrayarray];
for (int i = 0; i<count; i++) {
//获得成员属性
Ivar ivar = ivarList[i];
//获取成员属性名
NSString *name = [NSStringstringWithUTF8String:ivar_getName(ivar)];
//去掉属性名前面的_
NSString *key = [name substringFromIndex:1];
[properNameaddObject:key];
}
/*
NSLog(@"%@",properName);
(
"_name",
"_sex",
"_age"
)
*/
return [properName copy];
}
//归档
- (void)encodeWithCoder:(NSCoder *)aCoder
{
NSArray *properNames = [[self class] propertyOfSelf];
for (NSString * perperName in properNames) {
//动态创建get方法
SEL getSel = NSSelectorFromString(perperName);
[aCoder encodeObject:[self performSelector:getSel] forKey:perperName];
}
}
//解档
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [superinit]) {
NSArray *properNames = [[self class] propertyOfSelf];
for (NSString *properName in properNames) {
//动态拼接set方法
//1、获取属性名的第一个字符,并转化为大写
NSString *firstCharater = [[properName substringToIndex:1]uppercaseString];
//2、创建set方法
SEL setSel = NSSelectorFromString([NSStringstringWithFormat:@"set%@%@:",firstCharater,[properNamesubstringFromIndex:1]]);
[selfperformSelector:setSel withObject:[aDecoder decodeObjectForKey:properName]];
}
}
return self;
}