iOS用Runtime機制構建自己的XXModel(字典轉模型工具)

自從做iOS端心電SDK以來,已經一年基本沒有接觸網絡請求。最近由于SDK需求的改變需要解析網絡數據,這就難免要解析網絡請求返回的Json數據。

我們知道Json數據轉Model對象是由Json先轉換為NSDictionary對象,再轉換為model對象的。這個過程成熟的框架有JSModel,YYModel,MJExtension等等,但是如果只是用于NSDictionary轉Model不想用這些框架怎么辦?

NSDictionary轉Model對象的方式有兩種,KVC方式和Runtime方式。前者是遍歷字典中所有key,去模型中查找有沒有對應的屬性名然后賦值;后者剛好相反,遍歷模型中所有屬性名,去字典中查找然后賦值。那為什么我們提倡用Runtime方式呢?

Runtime:iOS的黑魔法啊,這樣寫顯得多有逼格!!!其實,實際的好處還是有的,Runtime方式相比JSModel等減少了大量不必要的代碼,而且接近底層的實現使得效率更高。當然,逼格高還是最重要的理由,沒有之一!

Model本質上是一個對象,所有的OC對象又都繼承自NSObject。所以我們給NSObject新建一個分類來實現NSDictionary轉Model。

1.新建一個NSObject的分類chDic2Model(在新建類和分類時最好給類名加一個屬于你自己的前綴,因為OC不像C++,JAVA等有namespace的概念!當然,如果你的代碼永遠只能被你自己使用到,也可不必多此一舉[baiyan...])

圖1

2.首先寫一個獲取當前類屬性的方法propertyList,由于這里用到了Runtime,記得先引入頭文件:#import<objc/runtime.h>

圖2

3.接下來就可以寫NSDictionary轉Model的對外接口了:

圖3

現在,這個工具就基本成型了。可以寫個Demo來跑一下了。

先建一個Model類,然后在主視圖里模擬一個json數據的字典,進行模型轉化:

圖3_1
圖3_2

怎么樣,是不是覺得很簡單,而且代碼量也很少就解決了問題。那么問題來了,作為一個強迫癥患者兼有著良好編碼習慣的碼者,實在不想在自己的代碼里看到score_art這樣的命名。

4.屬性名與字典key值不同時怎么破???(劃難點啦)

首先要知道要求model屬性名與字典key值相同,是為了在KVC賦值時一一對應。name我們先建立一個與屬性名有一一映射關系的中間表,使得該表字段和字典分別對應相等即可。

圖4_1

首先,新建一個函數用于返回Model屬性名和字典key值得映射關系,然后優化字典轉模型接口的實現

圖4_2
圖4_3

接著將模型不符合命名規則的屬性名改為駝峰命名,在.m文件中重寫屬性映射關


圖4_4
圖4_5

接下來,就可以跑起來試試了。

圖4_7

怎么樣?這下可有一點成就感了吧。我都碼類了,但是還有一個問題不知道大家有沒有注意到。我們在用JSModel時,關于上述問題的處理方式大致相同。但是在對象屬性名映射時,有些與字典key相同的字段就沒必要寫出來了。這樣做確實不錯,因為萬一屬性很多的話,這樣寫下去真心有點D疼。那么我們這個工具也能不能像JSModel那樣處理呢?

這也是我遇到的一個比較棘手的問題,因為字典轉模型的實現是寫在NSObject的分類里。這個時候我根本知不道將要定義的子類里哪個字段和對應字段key值不同,我只能都按照不同的方式建立一個映射,在KVC賦值的時候才擁有完整的屬性。這個下午的這個問題真是百思不得其姐哈......

這里這個屬性名,字段key處理起來挺繞的,當時可能饒了彎路。現在想想其實也不是很難,仔細理清思路就簡單多了。映射字典里是屬性名和字典key不一致的字段,可以copy一份帶轉化字典,然后根據映射關系把copy的那份字典里的key對應的值按映射關系轉移到新字典,同時把轉移了的字段刪除,那么剩下的就是屬性名和字典key一致的字段了,直接追加到新字典里就可以了。這樣得到的新字典就是key值與Model屬性名一致的字典,而且字典的value值都是轉化自原始字典。(我嚓,寫筆記的時候恍然里頭冒出個大悟來:這么簡單,比我下午采取的方式簡單多了。PS:做筆記總結對思路啟發還是挺管用的哈!!!)

圖4_8
圖4_9 可以在映射關系返回里只寫不一致的映射

原來,代碼實現是一回事。寫成總結性的筆記又是一回事,在寫筆記的同時既鞏固了既有知識,又能時不時在原有代碼的基礎上有新的啟發。作為一枚超低級的iOS開發,希望能在碼筆記的路上碼海無涯回頭無岸,學習使人快樂!

如果你有任何關于本文的問題或建議,可以在文末留言,我們一起學習交流。也可以加扣扣(995955216)微信(同qq)索要源代碼Demo。

--20171019夜


-------------------------------------------------------------------------------------


跟這個世界交手的許多年來,

你是否,

光彩依舊,

興趣盎然。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ————李霄峰 《喬治》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容