前言:
自己有編寫JSON轉(zhuǎn)模型框架計劃,在編寫之前首先對YYModel設(shè)計進(jìn)行分析,確定項目架構(gòu)以及借助圖示來理解框架設(shè)計思路,簡單說一下我對閱讀框架心路歷程,閱讀框架源代碼固然很重要,另一方面我認(rèn)為是最重要的,作者當(dāng)時是怎么想的,如何獲得靈感,只有了解作者的學(xué)習(xí)過程,例如在編寫時看過哪些開源框架,他的博客文章有木有提供線索,挖的越深收獲越大,只有這樣自己才能做到有所提高、學(xué)到了,這篇文章主要目的想完全依靠圖示和蘋果官方文檔、搜索引擎編寫一個小型的JSON轉(zhuǎn)模型框架,在群里你會發(fā)現(xiàn)有些大神和同學(xué)對YYModel的討論或者利用搜索引擎也看到過一些文章討論仿寫YYModel,如果僅僅是對著YYModel源代碼然后寫到另一個Demo項目中,我認(rèn)為只是抄抄源代碼罷了,這樣做的收獲一定是有限的,文章如有不足的地方還請見諒(時間匆忙,方法調(diào)用棧暫時先擱置),如有錯誤請指出修正。
參考資料
聲明類型文檔
聲明屬性文檔
Runtime參考文檔
YYModel
作者博客
設(shè)計思路
- 猜想作者編寫YYModel框架時借助類與對象的繼承層次關(guān)系獲得靈感,在閱讀YYKit發(fā)現(xiàn)作者編寫YYText框架時其實也是通過蘋果官方文檔提供的CoreText層次結(jié)構(gòu)圖獲得靈感,有空在發(fā)一篇關(guān)于YYText源碼解析,其他部分源碼也有所閱讀,作者同時也提供了一些線索,往后有機(jī)會一起發(fā)布。








或

或

- YYClassInfo層次關(guān)系

類對應(yīng)方法
YYClassInfo


![Upload Paste_Image.png failed. Please try again.]
NSObject +YYModel、NSArray + YYModel、NSDictionary + YYModel



1








技術(shù)點
- YYModel協(xié)議
- Category AssociatedObject
- systemLayoutSizeFittingSize And sizeThatFits
Category Use Method Swizzling
1.類中調(diào)用+load方法和-category中調(diào)用和+load方法調(diào)用順序是怎樣(類和分類同時重寫load方法)?
答:+load的執(zhí)行順序是先類,后category,而category的+load執(zhí)行順序是根據(jù)編譯順序決定的。
**2.類和-category中調(diào)用和+load方法調(diào)用順序是怎樣(只有分類重寫load方法)? **
答:先調(diào)用category +load方法,后類
- 在Objective-C實現(xiàn)擴(kuò)展方法可以使用Category來覆蓋系統(tǒng)方法,當(dāng)系統(tǒng)方法被覆蓋后,系統(tǒng)會優(yōu)先調(diào)用Category中的代碼,然后在調(diào)用原類中的代碼,如果我們在已有的Category想實現(xiàn)UIWebViewDelegate代理方法,往往就會使用Method Swizzling,可以通過新建UIWebView Category,在其分類使用+(load)Method Swizzling替換代理方法為自己構(gòu)造的方法(構(gòu)造的方法內(nèi)部計算UIWebView 高度并緩存高度),再執(zhí)行項目當(dāng)中UIWebViewDelegate代理方法
Category AssociatedObject
1.在category里面如何添加實例變量的?
答:在category里面是無法為category添加實例變量的。但是我們很多時候需要在category中添加和對象關(guān)聯(lián)的值,這個時候可以求助關(guān)聯(lián)對象來實現(xiàn)。
2.但是關(guān)聯(lián)對象又是存在什么地方呢? 如何存儲? 對象銷毀時候如何處理關(guān)聯(lián)對象呢?
關(guān)聯(lián)對象又是存在什么地方:AssociationsManager里面是由一個靜態(tài)AssociationsHashMap來存儲所有的關(guān)聯(lián)對象的。
如何存儲:所有對象的關(guān)聯(lián)對象都存在一個全局map里面。而map的的key是這個對象的指針地址(任意兩個不同對象的指針地址一定是不同的),而這個map的value又是另外一個AssociationsHashMap,里面保存了關(guān)聯(lián)對象的kv對。
對象銷毀時候如何處理關(guān)聯(lián)對象:runtime的銷毀對象函數(shù)objc_destructInstance里面會判斷這個對象有沒有關(guān)聯(lián)對象,如果有,會調(diào)用_object_remove_assocations做關(guān)聯(lián)對象的清理工作。
systemLayoutSizeFittingSize And sizeThatFits
LT_systemFittingHeightForConfiguratedWebView:該方法提供了兩套計算高度方式,分別是框架布局和自動布局
當(dāng)enforceFrameLayout為NO時使用自動布局自動布局的步驟:
(1)在計算高度前向 contentView 加了一條和 webView 寬度相同的寬度約束,強(qiáng)行讓 contentView 內(nèi)部的控件知道了自己父 view 的寬度,再反算自己被外界約束的寬度(給contentView添加約束)
(2)調(diào)用systemLayoutSizeFittingSize api為contentView自適應(yīng)高度
(3)移出contentView約束框架布局