MJExtension解析中的Key,Values轉換功能,映射


 

以下方法均稱為映射。

//當服務器回傳的模型名中出現系統關鍵字時可用以下方式進行修改。但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配置一次即可。不需要多次重復配置。因為系統在子類中找不到對應的屬性時會到父類中查找。這樣,我們不僅少寫代碼還能實現同樣的

效果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM