字典轉模型之KVC和MJExtension底層的實現

莫許IP屬地: 寧夏
字數 2,064

一 快速生成@property

1 當我們需要用模型去實現一個比較小的功能的時候,由于我們需要對plist文件進行轉化成模型,那么很有可能我們拿到的plist文件中的屬性很多,但是我們又因為只需要研究一個很小的功能,那么我們可以不需要將plist文件中的數據全部轉化為模型數據,我們只需要提取其中的一部分用來實現模型就可以,那么我們怎么做呢?

2 做法:展開某行,然后拷貝該行的item,然后將所有的item折起來,在將拷貝的東西復制到root上即可直接將一整個plist文件改為自己需要處理的文件,用該文件去處理一項特別小的功能.

3 但是由于plist文件中屬性太多,如果我們要創建一個模型,那么不得不寫這么多屬性,首先寫這些屬性都是無用功,沒什么技術含量,那么我們就想,有沒有什么辦法,可以一次性生成寫好的屬性,或者我們直接拷貝就可以了.那么,我們就想到了一個方法,通過一個方法,可以快速的將plist文件中的屬性生成@property的格式,我們只需要將結果拷貝,往@interface中粘貼就可以了.

4 代碼(通過一個分類就可以達到效果,如果需要就直接將分類拷貝到項目中就可以)

//快速生成@property屬性

- (void)creatPropetyCode

{

//創建可變的字符串

NSMutableString*codes = [NSMutableStringstring];

//由于plist文件外層都是字典,那么我們就遍歷字典

[selfenumerateKeysAndObjectsUsingBlock:^(id_Nonnull key,id_Nonnull value,BOOL* _Nonnull stop) {

//初始化變量,用來接收字符串的

NSString*code =nil;

//打印所有的value的類型,就知道BOOL到底是什么類型了.

//2016-03-26 23:06:50.867 03-RunTime(字典轉模型)[853:40171] __NSCFBoolean

NSLog(@"%@",[value class]);

//判斷value的類型,然后響應的憑借出不同類類型的字符串,滿足模型中定義屬性的需求

if([value isKindOfClass:[NSStringclass]]) {

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSString *%@;",key];

}elseif([value isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) BOOL *%@;",key];

}elseif([value isKindOfClass:[NSNumberclass]]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSNumber *%@;",key];

}elseif([value isKindOfClass:[NSDictionaryclass]]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSDictionary *%@;",key];

}elseif([value isKindOfClass:[NSArrayclass]]){

code = [NSStringstringWithFormat:@"@property (nonatomic, strong) NSArray *%@;",key];

}

//拼接字符串

[codes appendFormat:@"\n%@\n",code];

}];

//打印出結果

NSLog(@"%@",codes);

}

//從打印的結果來看,大部分的都能打印出來,但是類型是BOOL的卻打印不出來,我們也沒法通過判斷BOOL的類型來打印,因為BOOL就不是一個類.所以我們必須得想法辦知道BOOL的類型.


二 KVC底層實現

1 模型中的KVC方法

//KVC

[statusItem setValuesForKeysWithDictionary:dict];


2 問題:KVC底層是怎么實現通過字典對模型中的屬性賦值?

2.1 首先我么要明確KVC的使用條件:KVC的使用,必須要保證模型中的屬性名要和字典中的key一一對應,否則使用KVC運行時會報錯的.

2.2 setValuesForKeysWithDictionary:該方法本質其實就是遍歷字典中所有的key,去模型中查找對應的屬性,把值給模型屬性賦值

3 setValuesForKeysWithDictionary:該方法的底層實現原理:

//遍歷

[dict enumerateKeysAndObjectsUsingBlock:^(id_Nonnull key,id_Nonnull obj,BOOL* _Nonnull stop) {

//這行代碼才是真正給模型的屬性賦值

[s setValue:dict[@"source"] forKey:@"source"];

}];


4 遍歷字典的內部給屬性賦值遵循下面幾點條件

/*

[ssetValue:dict[@"source"]forKey:@"source"];

1.首先會去模型中查找有沒有setSource方法,直接調用set方法[ssetSource:dict[@"source"]];

2.去模型中查找有沒有source屬性,source= dict[@"source"]

3.去模型中查找有沒有_source屬性,_source= dict[@"source"]

4.調用對象的setValue:forUndefinedKey:直接報錯

*/

5 很多時候我們不需要plist文件中的所有的屬性都有作用,但是我們又想用kvc來實現給模型屬性賦值,那么我們有什么辦法呢?

5.1 由于我們都知道,如果在plist文件中的屬性和模型中的屬性并不是一一對應的關系,但是如果我們用KVC運行起來會直接報錯,打印出錯誤的結果是:setValue: forUndefinedKey:那么我們是不是想辦法不讓這錯誤提示出來呢.那么我們可以重寫系統的這個方法,里面什么都不需要做.這樣同樣能達到目的.

-(void)setValue:(id)value forUndefinedKey:(NSString *)key

{



三 MJExtension框架的底層實現(一級轉化)

MJ框架與KVC的底層實現不同點:

1 KVC是通過遍歷字典中的所有key,然后去模型中尋找對應的屬性

2 MJ框架是通過先遍歷模型中的屬性,然后去字典中尋找對應的key,所以用MJ框架的時候,模型中的屬性和字典可以不用一一對應,同樣能達到給模型賦值的效果.

3 代碼:

//返回一個創建好的模型

+ (instancetype)modelWithDict:(NSDictionary*)dict

{

//創建一個模型

idobjc = [[selfalloc] init];

intcount =0;

/*

方法:獲取成員變量列表

參數一:class獲取哪個類成員變量列表

參數二:count成員變量總數

*/

//成員變量數組指向數組第0個元素

Ivar *ivarList = class_copyIvarList(self, &count);

//遍歷所有成員變量

for(inti =0; i < count; i++) {

//獲取成員變量

Ivar ivar = ivarList[i];

//獲取成員變量名稱(將c轉為oc)

NSString*ivarName = [NSStringstringWithUTF8String:ivar_getName(ivar)];

//成員變量名稱轉換key(將成員變量前邊的"_"截取掉)

NSString*key = [ivarName substringFromIndex:1];

//從字典中取出對應value

idvalue = dict[key];

//給模型中屬性賦值(底層會去找對應的屬性和值)

[objc setValue:value forKey:key];

}

returnobjc;

}

四 附加知識點

1 const與宏的區別

1.1 編譯的時刻不一樣: 宏:預編譯 const:編譯

1.2 編譯檢查:宏不會做編譯檢查 const會

1.3 宏的好處:宏可以定義函數和方法 const不可以

1.4 宏壞處:大量使用宏,會導致預編譯時間過長

2 const作用

2.1 用于修飾右邊變量(基本變量,指針變量)

2.2 被const修飾變量只讀

2.3 有關const的面試題

int*constp1;// p1:只讀*p1:變量

constint*p2;// p2:變量*p2:只讀

intconst*p3;// p3:變量*p3:只讀

intconst*constp4;// p4:只讀*p4:只讀

constint*constp5;// p5:只讀*p5:只讀


3 const在開發當中的使用

3.1 const替換宏,宏:常用字符串或者基本數據定義成宏 -> const

3.2 修飾方法參數,讓方法參數只讀

4 static和extern

4.1 static:

—–>1> 修飾局部變量,只要被static修飾局部變量,這個局部變量的聲明周期就會延長(整個app運行過程中都在),作用域不變

—–>2> 修飾全局變量,只要被static修飾全局變量,這個全局變量只能在當前文件下使用

—–>3> 分配時刻:程序一運行的時候就會分配內存

4.2 extern:

—–>1> 僅僅只用來聲明外部全局變量

—–>2> extern不能用來定義變量

5 static和const聯合使用

5.1 被static修飾全局變量,全局變量只能在當前文件下使用

5.2 被const修飾,只讀.

6 開發中是如何避免重復定義?

做法:只要定義全局變量,都不能再自己的類中定義,一般開發中,我們會搞一個公共的文件來定義全局變量

五 總結

以上就是今天我給大家分享的知識點,很多知識點都寫得很詳細了,如果有不懂的可以給我留言,謝謝.我明天還會持續更新新的知識點.記得關注哦!!!

Baidu Button BEGIN

最后編輯于
©著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
1人點贊
總資產1共写了8716字获得2个赞共1个粉丝
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容