以下方法均称为映射。
//当服务器回传的模型名中出现系统关键字时可用以下方式进行修改。但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配置一次即可。不需要多次重复配置。因为系统在子类中找不到对应的属性时会到父类中查找。这样,我们不仅少写代码还能实现同样的
效果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结