runtime 字典轉模型,主要是利用runtime的class_copyIvarList方法來獲取到類中的所有的成員變量,字典轉模型的情況有以下幾種情況:
1、json對象中包含對象,這種情況下,如果model定義的屬性名和json中對象的參數一致,則不需要做多余的處理,否則要對model中定義的屬性名進行指定,已和json數據中的參數一致
2、json對象中包含數組,數組里面包含其他對象;這種情況下,要指定數組里面的對象對應的model模型,類似于YYModel里面的modelContainerPropertyGenericClass方法
例如:


例如圖一和圖二,圖一中定義的birthday和圖二中的birth是表達一個意思,但是名稱不一致,這時就需要將birthday指定成birth
圖一定義了一個User屬性對象user,這個user和圖二的user是一致的,所以即使是對象,也不需要做其他操作
其余注意的地方會在具體的代碼中實現(xiàn)出來
//? ? 創(chuàng)建當前類的實例變量
? ? idobjc = [[selfalloc]init];
? ? ididself =self;
? ? unsignedintcount;
//? ? 獲取類中所有的屬性變量
? ? Ivar* ivarList =class_copyIvarList(self, &count);
//? ? 遍歷所有的屬性變量
? ? for(inti =0; i < count; i ++) {
//? ? ? ? 根據下標獲取成員變量
? ? ? ? Ivarivar = ivarList[i];
//? ? ? ? 獲取成員變量名稱
? ? ? ? NSString * name = [NSString stringWithUTF8String:ivar_getName(ivar)];
//? ? ? ? 獲取當前的成員變量的類型
? ? ? ? NSString * ivarType = [NSString ?stringWithUTF8String:ivar_getTypeEncoding(ivar)];
//? ? ? ? 對類型type進行處理
? ? ? ? ivarType = [ivarTyp estringByReplacingOccurrencesOfString:@"\"" withString:@""];
? ? ? ? ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];
//? ? ? ? 處理獲取到的變量名——>對獲取的name進行截?。╪ame第一位為_)
? ? ? ? NSString * key = [name substringFromIndex:1];
//? ? ? ? 當字典中的字段和定義屬性名不一致的時候,需要對key進行轉換,以取得字典中的數據
? ? ? ? ididkey = [idself modelCustomPropertyMapper][key];
? ? ? ? if(idkey ==nil) {
? ? ? ? ? ? idkey = key;
? ? ? ? }
//? ? ? ? 根據key值獲取字典中對應的value
? ? ? ? id value = dict[idkey];
if(value) {
? ? ? ? ? ? [objc setValue:value forKey:key];
? ? ? ? }}
上述代碼中最主要的幾點就是runtime里面的幾個主要的方法來實現(xiàn):
1、class_copyIvarList方法,這個方法有兩個參數,一個是Class參數,傳入的是想獲取的model類,另外一個為unsigned int類型,會返回當前類所有的屬性變量的個數
2、ivar_getName 這個是獲取屬性變量名的名稱,例如_user
3、ivar_getTypeEncoding 這個方法是獲取當前屬性名的類型,返回的是:@"\User\"
針對json中的字段和定義的屬性不一致的時候,這時就需要指定屬性名為json中的字段

modelCustomPropertyMapper方法的實現(xiàn)是返回一個字典,字典類似于@{@"birthday":@"birth"},其中birthday是自己定義的屬性,birth是json中對應的字段,指定birthday為birth后,則可以在json中獲取到對應的數據
二、下面是針對model對象中包含model對象
//? ? ? ? 判斷當前的value是不是字典
? ? ? ? if([value isKindOfClass:[NSDictionary class]] && ![ivarType
hasPrefix:@"NS"]) {
? ? ? ? ? ? //? ? ? ? 獲取type的類型
? ? ? ? ? ? ClassmethodClass =NSClassFromString(ivarType);
//? ? ? ? ? ? 如果typeClass存在,則
? ? ? ? ? ? if(methodClass) {
? ? ? ? ? ? ? ? value = [methodClass modelWithDict:value];
? ? ? ? ? ? }
? ? ? ? }
上述代碼會獲取到當前model對應的類型,如果當前這個model來存在,則進行賦值
三、model對象中包含數組,這個時候就需要指定數組中對應model模型,例如:Person對象中,定義一個users數組,users數組里面包含的對象類型是User這個時候需要在方法arrayContainModelClass中指定:

這個處理好之后,就可以處理這種情況了:
//? ? ? ? 判斷當前的value 是不是數組
? ? ? ? if ([value isKindOfClass:[NSArray class]]) {
//? ? ? ? ? ? 獲取到數組value的type
? ? ? ? ? ? NSString*type = [idselfarrayContainModelClass][key];
//? ? ? ? ? ? 生成模型
? ? ? ? ? ? ClassmethodClass =NSClassFromString(type);
? ? ? ? ? ? NSMutableArray * mulary= [NSMutableArray array];
//? ? ? ? ? ? 遍歷字典數組,生成模型數組
? ? ? ? ? ? for(NSDictionary* dic in value) {
//? ? ? ? ? ? ? ? 字典轉模型
? ? ? ? ? ? ? ? idmodel = [methodClass modelWithDict:dic];
? ? ? ? ? ? ? ? [mulary addObject:model];
? ? ? ? ? ? }
? ? ? ? ? ? value = mulary;
? ? ? ? }
上述代碼理解起來不難,主要是遍歷數組,然后保存到value中,賦值