這篇水文主要是昨晚無(wú)意看到網(wǎng)上有些關(guān)于這個(gè)問(wèn)題,卻瞎寫的。后面還一群評(píng)論求帶飛统刮。械馆。呜投。。。別誤人子弟好么
+ (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)用一次团滥。這個(gè)load不同于普通方法,系統(tǒng)在調(diào)用時(shí)候报强,子類重寫不會(huì)影響父類的方法灸姊,分類也不會(huì)影響主類的方法。也就是各有個(gè)的秉溉,互不影響力惯。
此外,load方法是在加載image的時(shí)候調(diào)用的坚嗜,比main方法還前夯膀,不用在這里做耗時(shí)操作诗充。
可以在Xcode中加入 OBJC_PRINT_LOAD_METHODS
并設(shè)置為 YES 后苍蔬,將會(huì)打印出很多 +load
方法執(zhí)行時(shí)的信息。
+ (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 ... } }
有幾點(diǎn)要留意:
1蝴蜓、在首次用到這個(gè)類或這個(gè)類的子類的時(shí)候碟绑,會(huì)調(diào)用initialize
俺猿。所以如果某個(gè)類一直沒(méi)用到,那么initialize
就不會(huì)被調(diào)用格仲。
2押袍、每個(gè)類只會(huì)調(diào)用一次。(這里所說(shuō)的每個(gè)類凯肋,指的是以類名作為區(qū)分谊惭,分類和主類算同一個(gè)類。但是子類和父類算不同類)如果分類和主類都寫了initialize
侮东。只會(huì)調(diào)用分類的圈盔。如果有多個(gè)分類都復(fù)寫了,調(diào)用的是在編譯順序最后的一個(gè)分類的悄雅。
3驱敲、如果子類沒(méi)有復(fù)寫initialize
,那子類調(diào)用的時(shí)候就會(huì)按照父類的邏輯進(jìn)行調(diào)用宽闲,意思是:當(dāng)父類有分類復(fù)寫initialize
众眨,那么調(diào)用父類分類的initialize
,否則調(diào)用父類的initialize
容诬。所以這里可能會(huì)導(dǎo)致父類的initialize
被調(diào)用多次娩梨。
總結(jié)
1、能不用load
览徒,就不用姚建,盡量都放到initialize
去做。因?yàn)檫@個(gè)load
會(huì)拖慢應(yīng)用啟動(dòng)吱殉。
2掸冤、initialize
注意會(huì)被多次調(diào)用,且會(huì)受到分類的復(fù)寫影響友雳。