近两天一直再看MJExtension这个框架,这个框架是用来实现字典和模型互转的。开发过程中,我们经常遇到这种情况,比如说,获取到网络的Json数据后,我们需要转化成模型进行分析,这样比直接用字典来分析好处多多。该框架提供了简单的方法来实现这一功能。
设计思路:
该框架的设计是通过分类来实现的,因为模型对象都是最终继承自NSObject,所以设计了一个关于NSObject的分类。
代码分析:
该框架的核心部分是这个方法:
- (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
其中:keyValues
是要转化的Json数据。
该方法首先进行的时:
// 获得JSON对象
keyValues = [keyValues mj_JSONObject];
// 判断是哪种类型的数据,使用相关方法进行转换,获得字典
- (id)mj_JSONObject
{
if ([self isKindOfClass:[NSString class]]) {
return [NSJSONSerialization JSONObjectWithData:[((NSString *)self) dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
} else if ([self isKindOfClass:[NSData class]]) {
return [NSJSONSerialization JSONObjectWithData:(NSData *)self options:kNilOptions error:nil];
}
return self.mj_keyValues;
}
之后执行的方法当然就是遍历模型中的全部属性,参数是一个block
+ (void)mj_enumerateProperties:(MJPropertiesEnumeration)enumeration
{
// 获得成员变量
NSArray *cachedProperties = [self properties];
// 遍历成员变量
BOOL stop = NO;
for (MJProperty *property in cachedProperties) {
enumeration(property, &stop);
if (stop) break;
}
}
获得全部属性的方法是通过Runtime机制,读取了类中的属性列表。运行时库中提供了获得类的全部属性的方法:
// 返回一个指针数组,指针指向的是objc_property_t结构体
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
// 属性
typedef struct objc_property *objc_property_t;
// 运行库里提供获得属性名字的方法
const char *property_getName(objc_property_t prop)
{
return prop->name;
}
// 运行库里提供获得属性类型的方法
const char *property_getAttributes(objc_property_t prop)
{
return prop->attributes;
}
之后遍历每一个属性,生成一个MJProperty
对象,通过上面方法得到属性的名字和类型,该类型是一个对象,MJPropertyType
。设置好相关属性后,添加进数组,执行完for循环,获得全部属性。
之后执行block中的内容,首先驱逐
网友评论