Mantle源码学习笔记

作者: 升级打怪啊怪 | 来源:发表于2016-07-23 09:23 被阅读164次

    介绍一下Mantle吧,Mantle是应用于iOS中dictionary转为model的一个第三方库,功能强大,容错覆盖好。以下是我跟着源码调用栈看下去的内容,只是懂了个大概,里面还是有挺多黑魔法的,KVC ,runtime运行时方法去获取propertylist什么的,还有transformer挺巧妙的。看看源码挺好哒

    User *user =  [MTLJSONAdaptermodelOfClass:[Userclass]fromJSONDictionary:dicterror:nil];
    

    一、 初始化MTLJSONAdapter:

    MTLJSONAdapter *adapter = [[self alloc] initWithModelClass:modelClass];
    

    1、_JSONKeyPathsByPropertyKey = modelClass JSONKeyPathsByPropertyKey];
    这是Model遵守MTLJSONSerializing协议要实现的方法,指定对象的属性如何映射到不同的key path

    2、NSSet *propertyKeys = [self.modelClass propertyKeys];
    沿着superclass链向上遍历至MTLModel,获取model及父类中所有属性及其存储类型(除了存储类型为MTLPropertyStorageNone)

    3、 for (NSString *mappedPropertyKey in _JSONKeyPathsByPropertyKey)
    1)遍历JSONKeyPathsByPropertyKey变量,判断他们是否包含在propertyKeys集合中,
    a)如果在propertyKeys集合中找不到JSONKeyPathsByPropertyKey中的属性,判断他不是该model的一个property.
    b) 如果包含则获取对应属性keypath,这里keyPath有两种形式,字符串和数组
    2)_valueTransformersByPropertyKey = [self.class valueTransformersForModelClass:modelClass];获取model中每个属性对应的值转换的字典。
    具体实现过程:先去判断是否实现”属性名称”+”JSONTransformer”方法,如果实现进行动态调用并返回。如果未实现则判断是否实现JSONTransformerForKey这个方法,如果实现则进行调用并返回。如果未实现,则对属性结构进行判断,返回合适的值转换器。这里因为我们实现了URLJSONTransformer这个方法,所以代用完URLJSONTransformer就直接返回了。

    二、 将JSON转换为model最主要的方法:

    [adapter modelFromJSONDictionary:JSONDictionary error:error];
    

    1、classForParsingJSONDictionary??
    2、 遍历propertyKeys,for (NSString *propertyKey in [self.modelClass propertyKeys])
    1)id JSONKeyPaths = self.JSONKeyPathsByPropertyKey[propertyKey];
    获取property的的keypath.
    2)如果keypath是数组类型,遍历该数组,比较keypath和JSONDictionary中的路径,检查keypath是否合法。并取回JSONDictionary中该keypath下的value.
    id value = [JSONDictionary mtl_valueForJSONKeyPath:keyPath success:&success error:error];
    对keypath进行拆分,比如user.name.firstName先分解成user,name,firstName,然后一层一层的获取user[name][firstName].用了个for循环,来给用户反馈,到底错误在哪里。
    如果keypath是字符串类型,比较keypath和JSONDictionary中的路径,检查keypath是否合法。并取回JSONDictionary中该keypath下的value.
    3) 判断相应属性是否存在值转换器,如果存在,则对值进行相应转换。
    NSValueTransformer *transformer = self.valueTransformersByPropertyKey[propertyKey];
    如果该property的value是NSNull.null, Map NSNull -> nil
    a)如果 [transformer respondsToSelector:@selector(transformedValue:success:error:)]?? value = [errorHandlingTransformer transformedValue:value success:&success error:error];??
    else value = [transformer transformedValue:value];

    1. 最后将所有的值存储在字典dictionaryValue中,并调用modelWithDictionary:error通过KVC的方式验证并设置值
      id model = [self.modelClass modelWithDictionary:dictionaryValue error:error];
      a)MTLModel中,(instancetype)initWithDictionary:(NSDictionary *)dictionary error:(NSError **)error,通过KVC的方式初始化model实例
      // 将value标记为__autoreleasing,这是因为在MTLValidateAndSetValue函数中,可以会返回一个新的对象存在在该变量中
      __autoreleasing id value = [dictionary objectForKey:key]; //先是遍历了字典,获取值并验证是否为NSNull.null类型
      if ([value isEqual:NSNull.null]) value = nil; //接着通过KVC的方式为model实例验证并设置值
      BOOL success = MTLValidateAndSetValue(self, key, value, YES, error);

    写不出可以给别人看或者给自己看的东西,真是挺痛苦的。我是有用心去总结去写的,无奈结果总是不满意。why....

    相关文章

      网友评论

        本文标题:Mantle源码学习笔记

        本文链接:https://www.haomeiwen.com/subject/vfxwjttx.html