尝试写字典和模型转换

在没看MJ大神的MJExtension框架之前,自己模仿MJExtension功能,书写了一套转换转换规则(基本实现github上提出的实用功能)。

PS:不知道过两天看了MJ源码之后,会不会发现自己书写的代码思路和逻辑是不是全错了,会贻笑大方。。。

1,主要核心类NSObject分类

根据MJExtension实用习惯,NSObject (TBObject)分类对外提供5个函数

// ********************************字典转model****************************
+ (NSArray *)tb_objectWithKeyValueArray:(NSArray *)array;

+ (instancetype)tb_objectWithKeyValue:(id)source;


// ********************************model转字典****************************
- (NSDictionary *)tb_keyValue;

- (NSArray *)tb_keyValuesArrayWithObjectArray:(NSArray *)array;


// ********************************其他属性设置****************************
+ (NSDictionary *)tb_repalceKeyForValue;

+ (NSDictionary *)tb_classInArray;

与MJExtension框架相似,支持【模型中嵌套模型】,【模型中有个数组属性,数组里面又要装着其他模型】,【模型中的属性名和字典中的key不相同(或者需要多级映射)】等实用功能。

2, 实现思路(关键)

通过OC语言的运行时特性,获取类的所有属性值,以及属性(attr,attribute string of a property)

        const char *name = property_getName(pro);
        const char *nameAttr = property_getAttributes(pro);

再通过,key-value相应赋值

- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;

注意,类属性中可能会嵌套类外的model,甚至是类中嵌套数组中嵌套model,因此需要根据nameAttr属性判断,是基本类型还是复合类型属性,从根据实际赋值。
PS:之前因为学过Java,Java可以通过设置泛型,从而获取泛型的真实类型,但是使用MJExtendsion的时候一直不解,为什么要增加

+ (NSDictionary *)tb_classInArray;

指定泛型的真实类型,而不是通过泛型获取。我猜测的一个原因是因为,我在OC运行时根本找不到通过泛型获取类型的方法。
我判断的语句是一下,感觉太粗糙了 T T,不知道MJ大神有没更好的方法。

        NSString *pattern = @"@\"\\w+\"";        //匹配规则
        NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:nil];

3,递归与遍历函数的使用

由于model1里面可能会嵌套多个model2,而多个model2里面也可能会出现嵌套多个model3,所以需要使用递归函数依次完成封装。

+ (instancetype)tb_objectWithKeyValue:(id)source{
      .....
      value = [clz tb_objectWithKeyValue:value];
}

主要核心函数封装单个字典或者model,数组只是通过遍历每一个元素在调用单个封装函数即可。
比如:

+ (NSArray *)tb_objectWithKeyValueArray:(NSArray *)array;

函数内部调用即可

+ (instancetype)tb_objectWithKeyValue:(id)source;

你可能感兴趣的:(尝试写字典和模型转换)