由于项目需要,自己封装了一个基于Runtime的字典转模型的框架。话不多说,Show you the code.
Step1:创建一个NSObject的分类SXModel。
NSObject+SXModel.h
#import <Foundation/Foundation.h>
@interface NSObject (SXModel)
/**
字典转模型主方法
@param dict 字典
@return 模型
*/
+ (instancetype)sx_modelWithDict:(NSDictionary *)dict;
/**
字典数组转模型数组主方法
@param dictArray 字典数组
@return 模型数组
*/
+ (NSArray *)sx_modelArrayWithDictArray:(NSArray *)dictArray;
@end
NSObject+SXModel.m
#import "NSObject+SXModel.h"
#import <objc/runtime.h>
@implementation NSObject (SXModel)
const char *kPropertyListKey = "PropertyListKey";
///获取属性列表
+ (NSArray *)sx_objcProperties
{
// 获取关联对象的属性列表
NSArray *ptyList = objc_getAssociatedObject(self, kPropertyListKey);
// 如果 ptyList 有值,直接返回
if (ptyList) {
return ptyList;
}
// 记录属性个数
unsigned int outCount = 0;
// 调用运行时方法,取得类的属性列表
objc_property_t *propertyList = class_copyPropertyList([self class], &outCount);
// 准备属性列表数组
NSMutableArray *propertyArrayM = [NSMutableArray array];
// 遍历所有属性
for (unsigned int i = 0; i < outCount; i++)
{
// 从 property 中获得属性名称
const char *cProperty = property_getName(propertyList[i]);
// 将 C 字符串转化成 OC 字符串
NSString *ocProperty = [NSString stringWithUTF8String:cProperty];
[propertyArrayM addObject:ocProperty];
}
// 设置属性关联到对象
objc_setAssociatedObject(self, kPropertyListKey, propertyArrayM.copy, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// 释放
free(propertyList);
// 返回属性列表数组
return propertyArrayM.copy;
}
///字典转模型
+ (instancetype)sx_modelWithDict:(NSDictionary *)dict
{
// 实例化模型对象
id model = [[self alloc] init];
// 获得 self(模型对象) 的属性列表
NSArray *propertyList = [self sx_objcProperties];
// 遍历字典
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop)
{
// 判断 key 是否包含 propertyList 中
if ([propertyList containsObject:key])
{
// 说明属性存在,可以使用 KVC 设置数值
[model setValue:obj forKey:key];
}
}];
// 返回模型对象
return model;
}
///字典数组转模型数组
+ (NSArray *)sx_modelArrayWithDictArray:(NSArray *)dictArray
{
// 获得 self 的属性列表
NSArray *propertyList = [self sx_objcProperties];
// 准备模型数组
NSMutableArray *modelArrayM = [NSMutableArray arrayWithCapacity:dictArray.count];
// 遍历字典数组
[dictArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL * _Nonnull stop)
{
// 实例化模型对象
id modelObj = [[self alloc] init];
// 添加到模型数组
[modelArrayM addObject:modelObj];
// 遍历字典
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop)
{
// 判断 key 是否包含你在 propertyList 中
if ([propertyList containsObject:key])
{
// 说明属性存在,可以使用 KVC 设置数值
[modelObj setValue:obj forKey:key];
}
}];
}];
// 返回模型数组
return modelArrayM.copy;
}