MJExtension 源码阅读

近两天一直再看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中的内容,首先驱逐

你可能感兴趣的:(MJExtension 源码阅读)