load 與initialize的呼叫順序小結

碼鋒窩發表於2016-07-09

開發中實用方法固然是最貼近應用的,當一些程式原理還是要先搞清晰,根據查詢的一些資料,總結了一些load與initialize的呼叫。

APP啟動到執行main函式之前,程式就執行了很多程式碼
 
執行順序:
               將程式依賴的動態連結庫載入到記憶體 —> 載入可執行檔案中的所有符號,程式碼runtime解析被編譯的符號程式碼—>遍歷多有的class—>按繼承層級一次呼叫Class的load和category的load方法。

2個類初始化方法,+(void)load和+(void)initialize
 
[Constants alloc]  alloc將為Constants例項在堆上分配變數。這時呼叫一次initialize方法,而且僅呼叫一次,也就是說再次alloc操作的時候,不會再呼叫initialize方法了。
 
initialize 會在執行時僅被觸發一次,如果沒有向類傳送訊息的話,這個方法將不會被呼叫。這個方法的呼叫是執行緒安全的。父類會比子類先收到此訊息。

load的執行順序:
       1. 對於有依賴關係的兩個庫中,被依賴的類的load會優先呼叫。但在一個庫之內,呼叫順序是不確定的。
  1. 一個類的load方法不用寫明[super load],父類就會收到呼叫,並且在子類之前。也就是執行子類的load方法之前,當父類未載入時會先執行父類的Load方法。
  2. 分類category的方法在最後執行
  3. 執行完上面的才按compile sources的順序執行load。
  4. 對於一個類而言,沒有load方法實現就不會呼叫,不會考慮對NSObject的繼承。
 
initialize的執行順序
  • initialize的自然呼叫是在第一次主動使用當前類的時候(lazy,這一點和Java類的“clinit”的很像)。

  • 在initialize方法收到呼叫時,執行環境基本健全。

  • initialize的執行過程中是能保證執行緒安全的。

  • 和load不同,即使子類不實現initialize方法,會把父類的實現繼承過來呼叫一遍。注意的是在此之前,父類的方法已經被執行過一次了,同樣不需要super呼叫。


load和initialize的共同特點

load和initialize有很多共同特點,下面簡單列一下:

  • 在不考慮開發者主動使用的情況下,系統最多會呼叫一次

  • 如果父類和子類都被呼叫,父類的呼叫一定在子類之前

  • 都是為了應用執行提前建立合適的執行環境

  • 在使用時都不要過重地依賴於這兩個方法,除非真正必要 。

 

相關文章