ios runtime 實現(xiàn)json轉模型

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中,賦值

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1.ios高性能編程 (1).內層 最小的內層平均值和峰值(2).耗電量 高效的算法和數據結構(3).初始化時...
    歐辰_OSR閱讀 30,246評論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,666評論 1 32
  • 引導 對于從事 iOS 開發(fā)人員來說,所有的人都會答出「 Runtime 是運行時 」,什么情況下用 Runtim...
    Winny_園球閱讀 4,313評論 3 75
  • 對于從事 iOS 開發(fā)人員來說,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,812評論 7 64
  • 人間仙境何處尋, 塵都霧霾在清晨。 咫尺天涯無所見, 還道伊人是路人。
    xueshuai閱讀 190評論 3 3

友情鏈接更多精彩內容