美文网首页
iOS底层原理——Runtime

iOS底层原理——Runtime

作者: yangfei02821 | 来源:发表于2020-05-02 10:34 被阅读0次

实现思路:

遍历模型中所有属性,根据模型的属性名去字典中查找key,取出对应的的值,给模型的属性赋值

使用到的runtime函数:

拷贝实例变量列表(最后需要调用free释放)

  • Ivar *class_copyIvarList(Class cls, unsigned int *outCount)

获取成员变量的相关信息

  • const char *ivar_getName(Ivar v)
  • const char *ivar_getTypeEncoding(Ivar v)

1、首先获取类中所有成员变量,然后遍历取出每一个成员变量,获取变量名,即为字典中的key,从字典中取出value,然后进行赋值。
2、如果value是字典类型,就取出成员变量的属性类型,根据反射机制,生成类对象,然后对这个类对象进行字典赋值,遵循一级转换。
3、如果value是数组类型,判断对应类有没有实现字典数组转模型的协议,从中能够获取到字典数组中字典对应的模型,遍历字典数组,根据二级转换,生成模型数组。

一级转换

    id objc = [[self alloc] init];
    
    unsigned int count;
    
    // 获取类中的所有成员属性
    Ivar *ivarList = class_copyIvarList(self, &count);
    
    for (int i = 0; i < count; i++) {
        Ivar ivar = ivarList[i];
        
        // 获取成员属性名
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        
        // 处理成员属性名->字典中的key
        // 从第一个角标开始截取
        NSString *key = [name substringFromIndex:1];
        
        // 根据成员属性名去字典中查找对应的value
        id value = dict[key];

二级转换

    if ([value isKindOfClass:[NSDictionary class]]) {
            // 获取成员属性类型
            NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
            // 生成的是这种@"@\"User\"" 类型 -》 @"User"  在OC字符串中 \" -> ",\是转义的意思,不占用字符
            // 裁剪类型字符串
            NSRange range = [type rangeOfString:@"\""];
            
            type = [type substringFromIndex:range.location + range.length];
            range = [type rangeOfString:@"\""];
            // 裁剪到哪个角标,不包括当前角标
            type = [type substringToIndex:range.location];
            // 根据字符串类名生成类对象
            Class modelClass = NSClassFromString(type); 
            if (modelClass) {
                value  =  [modelClass modelWithDict:value];
            }
        }

三级转换

        if ([value isKindOfClass:[NSArray class]])
        {
            // 判断对应类有没有实现字典数组转模型数组的协议
            if ([self respondsToSelector:@selector(arrayContainModelClass)]) {
                
                // 转换成id类型,就能调用任何对象的方法
                id idSelf = self;
                // 获取数组中字典对应的模型
                NSString *type =  [idSelf arrayContainModelClass][key];
                // 生成模型
                Class classModel = NSClassFromString(type);
                NSMutableArray *arrM = [NSMutableArray array];
                // 遍历字典数组,生成模型数组
                for (NSDictionary *dict in value) {
                    // 字典转模型
                    id model =  [classModel modelWithDict:dict];
                    [arrM addObject:model];
                }
                // 把模型数组赋值给value
                value = arrM;
            }
        }

iOS-探究Runtime
iOS底层原理总结 - 探寻Runtime本质(一)
iOS底层原理总结 - 探寻Runtime本质(二)
iOS底层原理总结 - 探寻Runtime本质(三)
iOS底层原理总结 - 探寻Runtime本质(四)

相关文章

网友评论

      本文标题:iOS底层原理——Runtime

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