序列化框架MJExtension详解 + iOS ORM框架

干货,iOS ORM|序列化框架,还没完全写完,暂时也够用了,后续逐渐完善

代码(JModel/github)
(简书)

当开发中你的模型中属性名称和 字典(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中这么写:

    // 例子 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中么写:

    // 例子 4.
    [Person mj_setupObjectClassInArray:^NSDictionary *{
        return @{
                  @"users":@"User",// 或者
     //             @"users":[User class],
                  };
    }];

就是这么简单...

别急, 还没完, 下面来电思想层面的鸡汤...

没发现其实这些其实都是一次性的设置吗, 开发中我们这样的配置会十分平凡, 感觉上是不是很想抽的冲动...这一堆东西写在控制器里, 而且不一定只是一个控制器, 好多控制器都会有, 只要你需要转模型...

那怎么抽呢, 其实你发现没, 这和我们经常会抽一个专门管理常量的的类的做法, 是不是很类似, 这里我们也是这个需求

所以我们单独抽一个专门配置模型的 MJExtensionConfig类来管理这些配置, 这样不是方便许多吗!!!!所以我们将上面的那些配置统统拿到我们的配置类中

放到哪儿最合适, 当然是 + load中喽

// MJExtensionModelConfig.m
#import "MJExtensionModelConfig.h"
#import "Person.h"
#import "MJExtension.h"
//#import "User.h"

@implementation MJExtensionModelConfig

+ (void)load
{
    // 例子 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],
                 };
    }];
}

一样是好使的! 一样是好使的! 一样是好使的!重要的事说三遍...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容