Objective-C做爲一門面向對象語言,有類和對象的概念。編譯後,類相關的數據結構會保留在目標文件中,在運行時獲得解析和使用。在應用程序運行起來的時候,類的信息會有加載和初始化過程。
就像Application有生命週期回調方法同樣,在Objective-C的類被加載和初始化的時候,也能夠收到方法回調,能夠在適當的狀況下作一些定製處理。而這正是load和initialize方法能夠幫咱們作到的。安全
能夠看到這兩個方法都是以「+」開頭的類方法,返回爲空。一般狀況下,咱們在開發過程當中可能沒必要關注這兩個方法。若是有須要定製,咱們能夠在自定義的NSObject子類中給出這兩個方法的實現,這樣在類的加載和初始化過程當中,自定義的方法能夠獲得調用。
+load數據結構
顧名思義,+load方法在這個文件被程序裝載時調用。只要是在Compile Sources中出現的文件老是會被裝載,這與這個類是否被用到無關,所以+load方法老是在main函數以前調用。
調用方式:
會循環調用全部類的 +load 方法。注意,這裏是(調用分類的 +load 方法也是如此)直接使用函數內存地址的方式 (*load_method)(cls, SEL_load); 對 +load 方法進行調用的,而不是使用發送消息 objc_msgSend 的方式。
這樣的調用方式就使得 +load 方法擁有了一個很是有趣的特性,那就是子類、父類和分類中的 +load 方法的實現是被區別對待的。也就是說若是子類沒有實現 +load 方法,那麼當它被加載時 runtime 是不會去調用父類的 +load 方法的。同理,當一個類和它的分類都實現了 +load 方法時,兩個方法都會被調用。
要點:函數
補充上面一點,對於有依賴關係的兩個庫中,被依賴的類的+load會優先調用。但在一個庫以內,父、子類、類別之間調用有順序,不一樣類之間調用順序是不肯定的。spa
+initialize線程
+initialize 方法是在類或它的子類收到第一條消息以前被調用的,這裏所指的消息包括實例方法和類方法的調用,而且只會調用一次。initialize方法其實是一種惰性調用,也就是說若是一個類一直沒被用到,那它的initialize方法也不會被調用,這一點有利於節約資源。
調用方式:
runtime 使用了發送消息 objc_msgSend 的方式對 +initialize 方法進行調用。也就是說 +initialize 方法的調用與普通方法的調用是同樣的,走的都是發送消息的流程。換言之,若是子類沒有實現 +initialize 方法,那麼繼承自父類的實現會被調用;若是一個類的分類實現了 +initialize 方法,那麼就會對這個類中的實現形成覆蓋。
要點:對象
類別(Category)繼承
對於+initialize,只有最後一個類別執行,本類的+initialize和前面類別的+initialize被隱藏。
而對於+load,本類和本類的全部類別都執行,而且若是Apple的文檔中介紹順序同樣:先執行類自身的實現,再執行類別中的實現。
擴展生命週期
由於兩個方法只會被系統調用一次(除主動調用外),而且是線程安全的,能夠用來做爲單例的實現。(能夠用+initialize,+load有些隱患,看這裏)
�注意ip
問題內存
問題:
解答:
總結