iOS開發小貼士—NSObject的load與initialize方法

最近在研究無侵入的開屏廣告插入方式,受到眾多大神的啟示,利用NSObject的load方法。小白表示并不懂這個原理,上網查了資料,下來做一下整理。

1、NSObject

NSObject是絕大多是類的根類,它向其子類提供了基本的Runtime接口與objective-c Class的一些方法默認實現,其中它在.h文件中提供了兩個方法

+ (void)load;
Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.
+ (void)initialize;
Initializes the class before it receives its first message. 

這兩個方法由Runtime動態調用(Runtime懂吧,個人理解的意思就是OC在運行時動態的幫我們完成某些動作,推薦一篇文章http://www.lxweimin.com/p/927c8384855a

2、+ (void)load;

一、此方法調用時機很早,運行環境有不確定因素。具體點來說就是當Runtime將類加載時被調用,而且這個時機要先于appdelegate中的didFinishLaunchingWithOptions。

二、假如在一個庫中多個文件同時重寫+(void)load;,那么它的調用順序是不固定的,這就照應了上一條,運行環境的不確定因素。但是假如兩個類有依賴關系或者繼承關系,被依賴者和被繼承者+(void)load;會先調用,程序開發的時候需要考慮到這一點。

三、+(void)load;是不必寫明[super load]的,父類就會接收到調用。

四、Category的load也會收到調用,但順序上在主類的load調用之后。

五、只會被調用一次。

3、+ (void)initialize;

一、蘋果官方是這么描述的:該方法會在第一次初始化這個類之前被調用

二、initialize會在類接受第一個消息的線程中被調用。

三、initialize里的代碼不應該過于復雜,因為initialize會阻塞class的message sending。

四、當subclass沒有實現initialize方法的時候或者直接調用[super initialize]時,initialize會被重復調用。
為了防止initialize多次調用,可以在initialize方法中加入判斷當前調用者是否為當前類本身

+(void)initialize {
  if (self == [ClassName self]) {
    // ... do the initialization ...
  }
}

總結

上面廢話太多了總結來說就是你在類里重寫了+load方法,他就會被調用,而且是在didFinishLaunchingWithOptions之前。
比如文章開頭的無侵入廣告技術就是利用這點。
但+ initialize方法類似懶調用,就是只有你使用了該類才會調用該方法,調用在init之前。注意這兩個方法默認只會調用一次,但假如有子類,父類的initialize方法會被重復調用。load就絕不會出現多次調用的情況。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容