Load和Initialize

這篇水文主要是昨晚無意看到網(wǎng)上有些關(guān)于這個問題,卻瞎寫的。后面還一群評論求帶飛。。。。。別誤人子弟好么

+ (void)load

第一,先看蘋果爸爸的文檔
https://developer.apple.com/documentation/objectivec/nsobject/1418815-load?language=objc

Discussion
The load message is sent to classes and categories that are both dynamically loaded and statically linked, but only if the newly loaded class or category implements a method that can respond.
The order of initialization is as follows:
All initializers in any framework you link to.
All +load methods in your image.
All C++ static initializers and C/C++ attribute(constructor) functions in your image.
All initializers in frameworks that link to you.
In addition:
A class’s +load method is called after all of its superclasses’ +load methods.
A category +load method is called after the class’s own +load method.
In a custom implementation of load you can therefore safely message other unrelated classes from the same image, but any load methods implemented by those classes may not have run yet.

上面寫明了父類先于子類調(diào)用,分類調(diào)用晚于主類,大前提都是需要復(fù)寫load方法。且系統(tǒng)只調(diào)用一次。這個load不同于普通方法,系統(tǒng)在調(diào)用時候,子類重寫不會影響父類的方法,分類也不會影響主類的方法。也就是各有個的,互不影響。
此外,load方法是在加載image的時候調(diào)用的,比main方法還前,不用在這里做耗時操作。
可以在Xcode中加入 OBJC_PRINT_LOAD_METHODS 并設(shè)置為 YES 后,將會打印出很多 +load 方法執(zhí)行時的信息。

+ (void)initialize

先附上蘋果爸爸的文檔
https://developer.apple.com/documentation/objectivec/nsobject/1418639-initialize?language=occ

Discussion
The runtime sends initialize to each class in a program just before the class, or any class that inherits from it, is sent its first message from within the program. Superclasses receive this message before their subclasses.
The runtime sends the initialize message to classes in a thread-safe manner. That is, initialize is run by the first thread to send a message to a class, and any other thread that tries to send a message to that class will block until initialize completes.
The superclass implementation may be called multiple times if subclasses do not implement initialize—the runtime will call the inherited implementation—or if subclasses explicitly call [super initialize]. If you want to protect yourself from being run multiple times, you can structure your implementation along these lines:

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

有幾點要留意:
1、在首次用到這個類或這個類的子類的時候,會調(diào)用initialize。所以如果某個類一直沒用到,那么initialize就不會被調(diào)用。
2、每個類只會調(diào)用一次。(這里所說的每個類,指的是以類名作為區(qū)分,分類和主類算同一個類。但是子類和父類算不同類)如果分類和主類都寫了initialize。只會調(diào)用分類的。如果有多個分類都復(fù)寫了,調(diào)用的是在編譯順序最后的一個分類的。
3、如果子類沒有復(fù)寫initialize,那子類調(diào)用的時候就會按照父類的邏輯進行調(diào)用,意思是:當父類有分類復(fù)寫initialize,那么調(diào)用父類分類的initialize,否則調(diào)用父類的initialize。所以這里可能會導(dǎo)致父類的initialize被調(diào)用多次。

總結(jié)

1、能不用load,就不用,盡量都放到initialize去做。因為這個load會拖慢應(yīng)用啟動。
2、initialize注意會被多次調(diào)用,且會受到分類的復(fù)寫影響。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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