當開發中你的模型中屬性名稱和 字典(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