美文网首页
iOS 高级开发(3)之 Runtime 模型与字典的互转

iOS 高级开发(3)之 Runtime 模型与字典的互转

作者: iOS刘耀宗 | 来源:发表于2021-08-16 09:00 被阅读0次

Demo下载
利用 runtime 进行模型与字典的转换, 主要使用到 消息转发, 以及查看类属性相关的函数.
本篇文章也会很好的结合 runtime 里面的 API 来实现一个简单的模型与字典的互转.

字典转模型的思路
1:我们创建一个模型之后, 并且利用@property 声明属性之后. 会自动生成 get,以及 set 方法, 比如我们声明了一个

@property (nonatomic,copy) NSString *name;
//那么自然可以使用下面的代码. 这是最基本的东西哈
Dog *dog = [Dog new];
[dog setName:@"小狗"];

2: 既然我们知道一个对象都可以使用setXxxx方法进行赋值. 那么使用 runtime 的消息转发, 利用objc_msgSend 对模型的每一个setXxxx 进行调用赋值. 那么就完成字典到模型的转换.
PS: objc_msgSend 的调用必须使用类型强制转换. 具体的看下面的代码

//字典转模型
-(instancetype)initWithDic:(NSDictionary *)dic {
    if (self = [super init]) {
        for (NSString * key in dic.allKeys) {
            id value = dic[key];
            //注意首字母需要大写
            NSString *methodName = [NSString stringWithFormat:@"set%@:",key.capitalizedString];
            //根据名称获取方法
            SEL seletor = NSSelectorFromString(methodName);
            if (seletor) {
                //消息转发: 在调用 objc_msgSend需要进行一个类型强转,不然会报错
               ((void(*)(id,SEL,id))objc_msgSend)(self,seletor,value);
            }
           
        }
        return self;
    }
    return  nil;
}

以上只是一个简单的模型转字典, 并不能满足很多的需求, 如果需要满足更多的需求,需要自己进行完善, 这里只是提供一个思路

模型转字典:
思路: 我们需要得到一个字典, 那么字典就需要 key ---value.
key: 我们可以通过获取当前对象的属性列表来获取
value: 我们可以通过objc_msgSend 结合 get方法来获取

//模型转字典

-(NSDictionary *)modelConversionDic {
    unsigned int count = 0;
    //获取当前类的所有属性
    objc_property_t *properties = class_copyPropertyList([self class], &count);
    if (count != 0) {
        //创建字典
        NSMutableDictionary *dic = [@{} mutableCopy];
        for (int i = 0; i < count; i++) {
            //获取属性名称
            const void *propertyName = property_getName(properties[i]);
            //转换成 nsstring
            NSString *name = [[NSString alloc] initWithCString:propertyName encoding:NSUTF8StringEncoding];
            if (name) {
                SEL method = NSSelectorFromString(name);
                if (method) {
                    //获取当前的值
                    id value =  ((id(*)(id,SEL))objc_msgSend)(self,method);
                    //添加到字典中
                    [dic setValue:value forKey:name];
                } else {
                    [dic setValue:@"" forKey:name];
                    
                }
            }
        }
        //释放
        free(properties);
        return  dic;
    }
    return  nil;
}

总结一下:
字典转模型:
1: 遍历字典获取 key 和 value
2: objc_msgsend() ---调用 set 赋值
3:函数指针的写法
返回类型(名称)(param1,param2)

模型转字典
key 值----利用class_copyPropertyList
//获取当前的值
id value = ((id(*)(id,SEL))objc_msgSend)(self,method);

相关文章

网友评论

      本文标题:iOS 高级开发(3)之 Runtime 模型与字典的互转

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