以下方法均称为映射。

//当服务器回传的模型名中出现系统关键字时可用以下方式进行修改。但model中的属性名需要改写成更改后的名字。如原id位置要写成ID。

+ (NSDictionary *)mj_replacedKeyFromPropertyName{

    return @{@"typeName": @"typename", @"ID": @"id", @"desc": @"description"};

}

我们在工作当中可能还会碰到更加麻烦的问题。比如在上面的转换中,第一个属性typename,服务器人员设定了两个属性。typename和type。两个随机有一个

值回传,另一个为空,我们按上面的方法写就不好确定转换名了。我们可以用如下方式:

return @{@"typeName": [@"typename",@"type"] @"ID"@"id"@"desc"@"description"};

这样,系统会跟据服务器传回的typename或type中行判断,哪个有值即回传哪个。而其中写在前面的typename具有优先级,如果typename和type都有值,则

使用前面的typename给我们转换的typeName属性传值。

 

除了上面的问题,我们还可能碰到如下问题。比如服务器新增一个字典属性dic,他里面只有一条属性age.我们可以直接创建一个新model来对应它,但是就为了一个

属性创建一个类,似乎过于浪费。于是我们上面的语句可以修改为如下:

当然首先我们要在当前model中新创建一个属性age用来接收。

return @{@"typeName": [@"typename",@"type"] @"ID"@"id"@"desc"@"description",@"age":@"dic.age"};

注意最后一节,直接就将字典中的age取出来并存入当前model中了。 

 

假设有一天服务器给你一个dic的字典属性,然后里面有一个名为arr的数组属性,然后里面又包了一个age属性。

没问题,我们再将上面的语句改改

 return @{@"typeName": [@"typename",@"type"] @"ID"@"id"@"desc"@"description",@"age":@"dic.arr[0].age"};

注意最后一节。总的来说方法就是碰到字典就用"."来接下一层,碰到数组就用"[]"加一个下标来接下一层(例子中只有一个属性,所以下标为0)。

直到最后我们找到我们要的属性。所以只要明白了其中方法,我们也就一句话的事。

 

 又假设有一天服务器给我们一个myFirstName,这样的属性,然后要我们转成my_first_name这种型式,并且这种属性有几百条。我们一条条写就变得不

现实了,所以我们要用到下面方法。这也是mj中的一个方法,他会遍历所有的属性,并且将属性返回,这时我们就可以让属性按我们的需求进行修改。

注:mj_replacedKeyFromPropertyName121和mj_replacedKeyFromPropertyName方法二者只能用一个。否则冲突。他们都是对类名进行修改。

+ (id)mj_replacedKeyFromPropertyName121:(NSString *)propertyName{//121的意思是 one to one 一个属性转成另一个属性。

    NSMutableString * key = [NSMutableString string];  //生成一个用于接收的可变字符串

    for (NSInteger i = 0; i < propertyName.length; i++) {  //按字符长度进行循环

        unichar c = [propertyName characterAtIndex:i];  //获取对应位置的单个字符。

        if (c >= 'A' && c<='Z' ) {  //判断字符是否为大写

            [key appendFormat:@"_"];

            [key appendFormat:@"%c", c+32];  //大写转小写

        }else {  //字符为小时写按原样拼接

            [key appendFormat:@"%c",c];

        }

    }

        return key; //最后返回我们处理过的属性名。

}

 完成以上方法后,即使服务器有上千个属性也会按上面方法进行转换。

然而以上规则其实mj里面已经帮我们写好了。

return [propertyName mj_camelFromUnderline];  //下划线转驼峰

return [propertyName mj_underlineFromCamel];  //驼峰转下划线

*****************************************************************

 //当model中出现类型为NSArray的属性时记得用如下方法,靠诉系统数组中的属性要用什么model来进行转换。

+ (NSDictionary *)mj_objectClassInArray{

    return @{@"list": [XHListModel class]};

    //上面那句也可写成  return @{@"list": @"XHListModel"};效果一样。

}

****************************  ExtensionConfig *************************************

虽然用以上方法我们能很好的解决解析类所带来的问题。但是以上方法都是写在model.m中的。如果model多了,不仅找起来不方便 ,而且会使model

与第三方库的耦合性太强。改起来就很麻烦。这时我们可以新建一个ExtensionConfig类。然后导入model的头文件。然后我们在类中调用

+(void)load;方法。和+ (void)initialize;方法不同的是,+ (void)initialize;只在调用类时会运行一次,而+(void)load;则只要运行程序就会调用。

+(void)load{

    [AModel mj_setupObjectClassInArray:^NSDictionary *{

        code

    }];

    [BModel mj_setupReplacedKeyFromPropertyName:^NSDictionary *{

        code

    }];

    [CModel mj_setupReplacedKeyFromPropertyName121:^id(NSString *propertyName) {

        code

    }];

}

这样,所有的model配置都被放在一个文件当中,改起来方便。且我们的原model也非常简洁。万一要更换解析类也不会很麻烦。

 ****************************************************

如果我们发现在多个model中有比如id这种关键字或者多个相同的属性名要转换时,我们可以考虑创建一个BaseModel类,将相同部分属性放进去。这样我们

仅需要对BaseModel配置一次即可。不需要多次重复配置。因为系统在子类中找不到对应的属性时会到父类中查找。这样,我们不仅少写代码还能实现同样的

效果。