+load和+initialize

iOS開發(fā)面試時經(jīng)常被問到,+load方法和+initialize方法。今天主要用源碼分析下各自的調(diào)用機制。

+load方法

當APP啟動的時候,dyld便會開始加載庫和鏈接庫。load_images這個函數(shù)便會執(zhí)行,這個函數(shù)就會執(zhí)行+load方法。

圖一

這里邊有兩個重要的函數(shù):prepare_load_methodscall_load_methods,一個是準備load方法,一個是調(diào)用load方法。

1.prepare_load_methods方法

圖二

在準備load方法里邊又分為獲取類的load表和獲取分類的load表。

1.獲取類的load表
圖三

圖四
  1. 進入schedule_class_load函數(shù),將會遞歸的找到父類一直到NSObject。
  2. 將重載load方法的類添加到loadable_classes這個表里,按從父類到子類的順序。沒有重載load方法的類忽略。
2.獲取分類的load表

圖五

將所有重載load方法的分類加入到loadable_categories表里邊,沒有重載load方法的分類忽略。

2.call_load_methods方法

圖六

call_load_methods函數(shù)可以看到,先執(zhí)行了類的load方法調(diào)用,然后才執(zhí)行了分類的load方法調(diào)用。

3.+load方法總結(jié)

  1. +load方法在mian函數(shù)之前調(diào)用,因為dyld完成之后才會到main函數(shù)。
  2. 自動調(diào)用且由系統(tǒng)統(tǒng)一調(diào)用。
  3. 執(zhí)行順序:先是父類,然后是子類,最后才是分類。

+initialize方法

圖七

給+initialize方法加入斷點,可以很清楚的看到initialize方法是在main函數(shù)之后執(zhí)行的,且是被動調(diào)用的,因為它走的是發(fā)送消息流程的流程。
圖八

當這個已經(jīng)初始化且沒有發(fā)送過initialize方法時,就會執(zhí)行_class_initialize函數(shù)。這個函數(shù)有三個主要邏輯:如下四張圖.
圖九

圖十

圖十一

圖十二

  1. 遞歸的查找父類,直到NSObject類。
  2. +initialize方法只能被調(diào)用一次。
  3. 調(diào)用順序:
  • 父類有子類都有分類:先是父類的分類,再是子類的分類
  • 父類沒有分類子類有分類:先是父類,再是子類的分類
  • 父類有分類子類沒有:先是父類的分類,再是子類
  • 父類子類都沒有:先是父類,再是子類。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容