zoukankan      html  css  js  c++  java
  • 序列化框架MJExtension详解 + iOS ORM框架

    当开发中你的模型中属性名称和 字典(JSON/XML) 中的key 不能一一对应时, 或者当字典中嵌套了多层字典数组时..., 以及教你如何用 MJExtension 配置类来统一管理你的模型配置, 下面罗列了开发中常见的一些特殊情况, 请参考!(MJExtension/github)

    • 最基本用法:
      // 将字典转为模型
      Person *p = [Person mj_objectWithKeyValues:dict2];
      // 将 plist数据转成模型数组
      NSArrar *models =  [Person mj_objectArrayWithFile:@"xx.plist"];
      // 将字典数组转成模型数组, 最常用
      NSArrar *models =  [Person mj_objectArrayWithKeyValuesArray:dict]
    • 1 . 属性名和关键字冲突, 我们需要变更属性名, 比如 JSON 里是 id, 我们最好不要用 id, 又比如 discription, 和系统类重名了

      NSDictionary *dict = @{
                                 @"name":@"xiaofei",
                                 @"age":@24,
                                 @"id":@123456,
                                 @"description":@"haoshuai"
                                 };
      这时候我们属性就不能命名 id, description 了, 得换一个
      // person.h
      @interface Person : NSObject
      @property(nonatomic, strong) NSString * name;
      @property(nonatomic, assign) NSInteger age;
      @property(nonatomic, strong) NSString * descrip;
      @property(nonatomic, strong) NSString *ID;
      
      @end
      
      光换名字不行, 我们得把换的名字和字典中的 key联系起来, 不然转换成模型后, 属性是没有值得
      
      MJExtension 提供了一个+ mj_replacedKeyFromPropertyName的方法(该方法在模型中使用), 可以把原来字典中的 key 和你修改后的属性再关联起来, 你只要告诉它, 想把什么属性名替换为原来的那个 key
      // person.m
      + (NSDictionary *)mj_replacedKeyFromPropertyName
      {
          return @{
                   // 模型属性: JSON key, MJExtension 会自动将 JSON 的 key 替换为你模型中需要的属性
                   @"ID":@"id",
                   @"descrip":@"description",
                   };
      }

      2 . 字典中又嵌套了一层字典, 示例中的 address, 同时你只需要其中的某一个属性, 没必要再单独搞个模型来转, 你就可以这么做:

      • 注意如果单独搞个模型对应这个字典, MJExtension 是会自动将字典转成模型的, 只有当是字典数组时(字典数组嵌套字典数组才需要其它操作, 参考第4条)
      • NSDictionary *dict = @{
                                   @"name":@"xiaofei",
                                   @"age":@24,
                                   @"id":@123456,
                                   @"description":@"haoshuai",
                                   
                                   @"address":@{@"province":@"chaohu"},
                                   };

        还是在mj_replacedKeyFromPropertyName中关联, 你只需要将 key 用.连接起来就行了

      • // person.m
        + (NSDictionary *)mj_replacedKeyFromPropertyName
        {
            return @{
                     // 模型属性: JSON key, MJExtension 会自动将 JSON 的 key 替换为你模型中需要的属性
                     @"ID":@"id",
                     @"descrip":@"description",
                     @"address":@"address.province"
                     };
        }

        假如 address key 对应的字典中有很多key,而且嵌套比较深, 不过你仅仅只是想要一个数据, 你还是不想单独搞个模型, 你就还是可以点下去, 比如说下面更复杂的情况, 你只想取出里面狗的名字

        NSDictionary *dict = @{
                                   @"name":@"xiaofei",
                                   @"age":@24,
                                   @"id":@123456,
                                   @"description":@"haoshuai",
                                   
                                   @"address":@{@"province":@"chaohu",
                                                @"school":@"sitanfu",
                                                @"family":@[@"mm", @"dd", @{@"dog":@"wangcai"}],
                                                },
                                   };
        
        + (NSDictionary *)mj_replacedKeyFromPropertyName
        {
            return @{
                     // 模型属性: JSON key, MJExtension 会自动将 JSON 的 key 替换为你模型中需要的属性
                     @"ID":@"id",
                     @"descrip":@"description",
        //             @"address":@"address.province",
                     @"dogName":@"address.family[2].dog",
                     };
        }
        3 . 可能一些变态的公司一定要让你用驼峰命名, 但服务器返回的数据又都是该死的下划线, 你该怎么办, 别怕, 叔叔教你不用在上一个方法里一个一个对应着改...
        这里要用到 + mj_replacedKeyFromPropertyName121这个方法, 121, 代表 oneToOne...MJ 说的...


        NSDictionary *dict2 = @{
                                    @"name_key":@"xiaoming",
                                    @"age_key":@20,
                                    @"info_key":@"handsome",
                                    };
        
        // person.h
        @property(nonatomic, strong) NSString * nameKey;
        @property(nonatomic, strong) NSString * infoKey;
        @property(nonatomic, assign) NSInteger ageKey;
        
        // person.m
        + (NSString *)mj_replacedKeyFromPropertyName121:(NSString *)propertyName
        {
            // propertyName 是你属性名, 你把属性名格式化成对应字典中 key, 返回就可以了
            
            NSMutableString *key = [NSMutableString string];
            // 遍历propertyName的所有字符
            for (NSInteger i = 0; i < propertyName.length; i++) {
                unichar c = [propertyName characterAtIndex:i];
                if (c >= 'A' && c <= 'Z') { // 大写字母
                    [key appendFormat:@"_%c", c + ('a' - 'A')];
                } else { // 非大写字母
                    [key appendFormat:@"%c", c];
                }
            }
            return key;
        // 其实 MJ的框架里已经实现了这个方法, 你只需一句代码:请跟着我心中默默念一句: 卧槽...
        //   return [propertyName mj_underlineFromCamel];
        }

        4 . 当字典中又包含字典数组时, 模型嵌套, 你要告诉 MJExtension 嵌套模型的类名
        还是先讲在模型类中的做法:

        NSDictionary *dict2 = @{
                                    @"name_key":@"xiaoming",
                                    @"age_key":@20,
                                    @"info_key":@"handsome",
                                    @"users": @[@{@"name":@"xx"}, @{@"name":@"yy"}, @{@"name":@"zz"}],
                                    };
        
        @property(nonatomic, strong) NSString * nameKey;
        @property(nonatomic, strong) NSString * infoKey;
        @property(nonatomic, assign) NSInteger ageKey;
        @property(nonatomic, strong) NSArray * users;
        
        // person.m
        + (NSDictionary *)mj_objectClassInArray
        {
            return @{
                     @"users":@"User",// 或者
        //             @"users":[User class],
                     };
        }

        5 . 前面都是些常规用法, 下面开始装逼...
        所谓高级用法其实就是严密的逻辑加科学的管理(抽抽抽!!!)加牛逼的架构加首席科学家的思想云云...不扯了...

        恩恩..

        以上所有操作都是在我们的模型里面完成的, 这样就对模型造成了一定的污染, 下次我们代码万一不用 MJExtension 了, 那这些模型就都不能用了, 那就哭吧...所以大神 MJ 早就给我们做好了一切, 然后一群菜狗们屁颠屁颠拿来装逼了, 比如本人...

        以上的所有操作都可以不用再模型中操作, 我们可以拿出来放在外面, 比如某个 viewController 里面统一设置

        例子2中这么写, 方法名差不多,只不过换成了 block 回调

        // 例子 2.
            [Person mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
                return @{
                          // 模型属性: JSON key, MJExtension 会自动将 JSON 的 key 替换为你模型中需要的属性
                          @"ID":@"id",
                          @"descrip":@"description",
             //             @"address":@"address.province",
                          @"dogName":@"address.family[2].dog",
                          };
        
            }];
        // 例子 3.
            [Person mj_setupReplacedKeyFromPropertyName121:^NSString *(NSString *propertyName) {
                // propertyName 是你属性名, 你把属性名格式化成对应字典中 key, 返回就可以了
                
                    NSMutableString *key = [NSMutableString string];
                    // 遍历propertyName的所有字符
                    for (NSInteger i = 0; i < propertyName.length; i++) {
                        unichar c = [propertyName characterAtIndex:i];
                        if (c >= 'A' && c <= 'Z') { // 大写字母
                            [key appendFormat:@"_%c", c + ('a' - 'A')];
                        } else { // 非大写字母
                            [key appendFormat:@"%c", c];
                        }
                    }
                    return key;
        // 其实 MJ的框架里已经实现了这个方法, 你只需一句代码:请跟着我心中默默念一句: 卧槽...
        //   return [propertyName mj_underlineFromCamel];
            }];
        // 例子 4.
            [Person mj_setupObjectClassInArray:^NSDictionary *{
                return @{
                          @"users":@"User",// 或者
             //             @"users":[User class],
                          };
            }];
        别急, 还没完, 下面来电思想层面的鸡汤...
        
        没发现其实这些其实都是一次性的设置吗, 开发中我们这样的配置会十分平凡, 感觉上是不是很想抽的冲动...这一堆东西写在控制器里, 而且不一定只是一个控制器, 好多控制器都会有, 只要你需要转模型...
        
        那怎么抽呢, 其实你发现没, 这和我们经常会抽一个专门管理常量的的类的做法, 是不是很类似, 这里我们也是这个需求
        
        所以我们单独抽一个专门配置模型的 MJExtensionConfig类来管理这些配置, 这样不是方便许多吗!!!!所以我们将上面的那些配置统统拿到我们的配置类中
        
        放到哪儿最合适, 当然是 + load中喽
        别急, 还没完, 下面来电思想层面的鸡汤...
        
        没发现其实这些其实都是一次性的设置吗, 开发中我们这样的配置会十分平凡, 感觉上是不是很想抽的冲动...这一堆东西写在控制器里, 而且不一定只是一个控制器, 好多控制器都会有, 只要你需要转模型...
        
        那怎么抽呢, 其实你发现没, 这和我们经常会抽一个专门管理常量的的类的做法, 是不是很类似, 这里我们也是这个需求
        
        所以我们单独抽一个专门配置模型的 MJExtensionConfig类来管理这些配置, 这样不是方便许多吗!!!!所以我们将上面的那些配置统统拿到我们的配置类中
        
        放到哪儿最合适, 当然是 + load中喽
         
        从如下转载:https://www.jianshu.com/p/11a8e15f7d2b
  • 相关阅读:
    [swustoj 243] 又是一年CET46
    [转] 解析Qt资源文件使用
    [转] Qt 多线程学习
    USACO全部测试数据
    [HUD 1195] Open the Lock
    Vue-cli+webpack单页模式详解(转)
    关于vs code终端执行webpack命令报错问题(转)
    git使用相关记录
    关于flex布局兼容
    canvas绘画交叉波浪
  • 原文地址:https://www.cnblogs.com/edensyd/p/9139025.html
Copyright © 2011-2022 走看看