利用Runtime运行机制(消息机制)快速实现JSON到数据模型的转换

现在的ios开发中,我们通常会使用MVC模式。当我们拿到数据的时候,我们要把数据转成模型使用。

一般情况我们拿到的数据都是字典。这是我们就需要将字典转成模型对象了。

当对象的属性很少的时候,我们可以直接单独写出字典的键值,进行转换。

_属性 = dict["键"]

当对象的属性很多的时候,我们可以利用KVC批量设置。

setValuesForKeysWithDictionary:<#(NSDictionary *)#>

但是KVC批量转的时候,有个致命的缺点,就是当字典中的键,在对象属性中找不到对应的属性的时候

会报错。

这个时候,我们不妨反过来想一下。我们先获取到对象所有的属性名,然后加入到一个数组里面,然后再遍历,赋值。

在程序运行的时候,抓取对象的属性,这时候,要利用到运行时机制了,详情见下面的代码

+ (NSArray *)propertyList {

//0. 判断是否存在关联对象,如果存在,直接返回

/**

1> 关联到的对象

2> 关联的属性 key

提示:在 OC 中,类本质上也是一个对象

*/

NSArray *pList =objc_getAssociatedObject(self, propertiesKey);

if(pList !=nil) {

return pList;

}

//1. 获取`类`的属性

/**

参数

1> 类

2> 属性的计数指针

*/

unsigned int count =0;

//返回值是所有属性的数组 objc_property_t

objc_property_t *list = class_copyPropertyList([self class], &count);

NSMutableArray *arrayM =[NSMutableArray arrayWithCapacity:count];

//遍历数组

for(unsigned int i =0; i < count; ++i) {

//获取到属性

objc_property_t pty =list[i];

//获取属性的名称

const char *cname =property_getName(pty);

[arrayM addObject:[NSString stringWithUTF8String:cname]];

}

NSLog(@"%@", arrayM);

//释放属性数组

free(list);

//设置关联对象

/**

1> 关联的对象

2> 关联对象的 key

3> 属性数值

4> 属性的持有方式 retain, copy, assign

*/

objc_setAssociatedObject(self,propertiesKey,arrayM,OBJC_ASSOCIATION_COPY_NONATOMIC);

return arrayM.copy;

}

上面的代码中,有两段 判断是否有关联对象,和 设置关联对象的代码。是为了不重复执行此方法。


在获取到上面的属性数组之后,可以写字典转模型的方法了

+ (instancetype)objectWithDict:(NSDictionary *)dict {

id obj =[[self alloc] init];

// [obj setValuesForKeysWithDictionary:dict];

NSArray *properties =[self propertyList];

//遍历属性数组

for(NSString *key in properties) {

   //判断字典中是否包含这个key

   if(dict[key] !=nil) {

   //使用 KVC 设置数值

   [obj setValue:dict[key] forKeyPath:key];

   }

}

return obj;

}

你可能感兴趣的:(利用Runtime运行机制(消息机制)快速实现JSON到数据模型的转换)