Demo下载
利用 runtime 进行模型与字典的转换, 主要使用到 消息转发, 以及查看类属性相关的函数.
本篇文章也会很好的结合 runtime 里面的 API 来实现一个简单的模型与字典的互转.
字典转模型的思路
1:我们创建一个模型之后, 并且利用@property 声明属性之后. 会自动生成 get,以及 set 方法, 比如我们声明了一个
@property (nonatomic,copy) NSString *name;
//那么自然可以使用下面的代码. 这是最基本的东西哈
Dog *dog = [Dog new];
[dog setName:@"小狗"];
2: 既然我们知道一个对象都可以使用setXxxx方法进行赋值. 那么使用 runtime 的消息转发, 利用objc_msgSend 对模型的每一个setXxxx 进行调用赋值. 那么就完成字典到模型的转换.
PS: objc_msgSend 的调用必须使用类型强制转换. 具体的看下面的代码
//字典转模型
-(instancetype)initWithDic:(NSDictionary *)dic {
if (self = [super init]) {
for (NSString * key in dic.allKeys) {
id value = dic[key];
//注意首字母需要大写
NSString *methodName = [NSString stringWithFormat:@"set%@:",key.capitalizedString];
//根据名称获取方法
SEL seletor = NSSelectorFromString(methodName);
if (seletor) {
//消息转发: 在调用 objc_msgSend需要进行一个类型强转,不然会报错
((void(*)(id,SEL,id))objc_msgSend)(self,seletor,value);
}
}
return self;
}
return nil;
}
以上只是一个简单的模型转字典, 并不能满足很多的需求, 如果需要满足更多的需求,需要自己进行完善, 这里只是提供一个思路
模型转字典:
思路: 我们需要得到一个字典, 那么字典就需要 key ---value.
key: 我们可以通过获取当前对象的属性列表来获取
value: 我们可以通过objc_msgSend 结合 get方法来获取
//模型转字典
-(NSDictionary *)modelConversionDic {
unsigned int count = 0;
//获取当前类的所有属性
objc_property_t *properties = class_copyPropertyList([self class], &count);
if (count != 0) {
//创建字典
NSMutableDictionary *dic = [@{} mutableCopy];
for (int i = 0; i < count; i++) {
//获取属性名称
const void *propertyName = property_getName(properties[i]);
//转换成 nsstring
NSString *name = [[NSString alloc] initWithCString:propertyName encoding:NSUTF8StringEncoding];
if (name) {
SEL method = NSSelectorFromString(name);
if (method) {
//获取当前的值
id value = ((id(*)(id,SEL))objc_msgSend)(self,method);
//添加到字典中
[dic setValue:value forKey:name];
} else {
[dic setValue:@"" forKey:name];
}
}
}
//释放
free(properties);
return dic;
}
return nil;
}
总结一下:
字典转模型:
1: 遍历字典获取 key 和 value
2: objc_msgsend() ---调用 set 赋值
3:函数指针的写法
返回类型(名称)(param1,param2)
模型转字典
key 值----利用class_copyPropertyList
//获取当前的值
id value = ((id(*)(id,SEL))objc_msgSend)(self,method);
网友评论