iOS底層原理之分類的加載

前言

咱們在上一篇iOS底層原理之類的加載中探索了關於類的加載,在結尾部分咱們也注意到了處理分類的代碼,此次咱們研究下分類的加載。markdown

分類的本質

研究分類的加載,咱們先看下分類的本質。函數

經過源碼探究分類本質

咱們在源碼中搜索category_t,搜索結果以下從上面咱們能夠獲得分類的本質是category_t結構體,結構體裏面有namecls實例方法列表類方法列表協議列表屬性列表類屬性列表元類等信息,其中正由於分類中有屬性列表,因此分類才能夠動態添加 屬性分類只能聲明屬性,因爲沒有set、get方法,因此須要動態添加)。post

分類的加載

咱們以LGPerson爲主類,咱們添加LGPerson+LGALGPerson+LGB兩個分類。 咱們從上一篇類的加載中得知最終會經過realizeClassWithoutSwift函數將類的信息關聯起來,而realizeClassWithoutSwift函數經過methodizeClass函數來處理分類。spa

methodizeClass函數分析

methodizeClass函數中咱們能夠看到最終是經過attachToClass函數來將分類添加到主類上的。3d

attachToClass函數

咱們查看attachToClass函數代碼從中能夠看到attachToClass函數最終又調用了attachCategories函數code

attachCategories函數

這個函數裏面處理了分類的方法、屬性、協議等。orm

分類加載反推路徑分析

  • 咱們將斷點打在attachCategories函數中的LGPerson判斷部分,運行代碼到斷點位置,打印堆棧信息經過上圖咱們能夠發現實際上分類加載反推路徑attachCategoriyes -> load_categories_nolock(執行兩次) -> loadAllCategories -> load_images

分類加載正反推路徑總結

主類分類混合加載

主類跟分類混合加載主要區分在是不是懶加載類,便是否實現了+load函數get

懶加載類與懶加載分類混合

咱們在main函數中打下斷點,如圖所示咱們發現此時僅僅執行了readClsss函數,經過咱們前面dyld與objc的關聯咱們知道,這個readClass函數在編譯階段就會執行,所以得知此時並無加載類和其分類。咱們繼續執行代碼到NSLog處,此時咱們發現已經加載了類和其分類,所以咱們能夠總結出來:懶加載類與懶加載分類混合,加載實際推遲到第一次消息轉發時,即本文中的[LGPerson alloc]時源碼

非懶加載類與懶加載分類混合

仍是同懶加載類與懶加載分類混合分析相同,從圖中咱們發現還有執行[LGPerson alloc]時,類已經被加載了,即在編譯階段就已經被加載了it

非懶加載類與非懶加載分類混合

從上圖中咱們得知也是在編譯階段加載了,只是在attachToClass函數中執行了兩次load_categories_nolock函數

懶加載類與分懶加載分類混合

從上圖中得知懶加載類與分懶加載分類混合時,會迫使主類在編譯階段加載

總結

相關文章
相關標籤/搜索