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
  • 相关阅读:
    Java实现 LeetCode 242 有效的字母异位词
    Java实现 LeetCode 212 单词搜索 II
    Java实现 LeetCode 212 单词搜索 II
    Java实现 LeetCode 212 单词搜索 II
    Java实现 LeetCode 212 单词搜索 II
    Java实现 LeetCode 344 反转字符串
    Java实现 洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk
    Java实现 洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk
    Java实现 洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk
    Java实现 洛谷 P1208 [USACO1.3]混合牛奶 Mixing Milk
  • 原文地址:https://www.cnblogs.com/edensyd/p/9139025.html
Copyright © 2011-2022 走看看