+ Load 和 +initalize

+ Load 和 +initalize 方法

有時(shí)候我們希望類(lèi)先執(zhí)行某些一次性的初始化操作再使用,NSObject根類(lèi)中有兩個(gè)可以實(shí)現(xiàn)這種初始化操作的方法,這就是+Load+initailze方法

+Load

調(diào)用時(shí)機(jī)

對(duì)于加入運(yùn)行期系統(tǒng)的每個(gè)類(lèi)以及它的分類(lèi)來(lái)說(shuō),必定會(huì)調(diào)用此方法,而且只會(huì)被調(diào)用一次,通常是在應(yīng)用程序啟動(dòng)的時(shí)候,執(zhí)行時(shí)機(jī)在main函數(shù)之前!并且先調(diào)用父類(lèi)的+load再調(diào)用子類(lèi)的.

@implementation FatherClass
+(void)load {
NSLog(@"%s",__func__);
}
@end

@interface SonClass : FatherClass
@end
@implementation SonClass
+(void)load {
NSLog(@"%s",__func__);
}
@end
//輸出臺(tái):
+[FatherClass load]
+[SonClass load]

如果分類(lèi)中也實(shí)現(xiàn)了該方法,那么先調(diào)用本類(lèi)的再調(diào)用分類(lèi)的

@implementation FatherClass
+(void)load {
NSLog(@"%s,%@",__func__,self);
}
@end
@implementation FatherClass (category)
+(void)load {
NSLog(@"%s,%@",__func__,self);
}
@end
輸出臺(tái):
//+[FatherClass load],FatherClass
//+[FatherClass(category) load],FatherClass

如果兩個(gè)沒(méi)有繼承關(guān)系的類(lèi)都實(shí)現(xiàn)了+load方法,那么它的調(diào)用順序取決于誰(shuí)先被加到運(yùn)行期環(huán)境中


上圖中的AnyObject類(lèi)與FatherClass類(lèi)都繼承自NSObject,但是FatherClass先被加入進(jìn)運(yùn)行期環(huán)境,所以它的+load方法會(huì)先被執(zhí)行.

輸出臺(tái):
+[FatherClass load]
+[SonClass load]
+[AnyObject load]
使用注意點(diǎn):
  • 在+load的調(diào)用時(shí)機(jī),系統(tǒng)還處于"脆弱"狀態(tài),雖然系統(tǒng)的庫(kù)已經(jīng)被加載進(jìn)運(yùn)行期系統(tǒng),但是我們自己編寫(xiě)的類(lèi),或者引用的其他的類(lèi)庫(kù)中的類(lèi)不一定已經(jīng)可以使用,所以在+load中要盡量避免初始化其他的對(duì)象. 比如下面的代碼就是不安全的
@implementation FatherClass
+(void)load {
NSLog(@"%s",__func__);
AnyObject *anyObject = [AnyObject new];
// use anyObject...
}
@end

當(dāng)然AnyObject這個(gè)類(lèi)使我們自己寫(xiě)的,我們可能通過(guò)Complie Sources知道它加載的順序(這不是一個(gè)好辦法),但是是用其他類(lèi)庫(kù)我們就不得而知.如果恰好在AnyObject中使用了+load方法來(lái)進(jìn)行某些初始化操作來(lái)賦予這個(gè)類(lèi)某些特性,并且這個(gè)類(lèi)被載入的晚,那么這就有問(wèn)題了.

  • +load方法不像普通的方法那樣遵循繼承規(guī)則,如果一個(gè)類(lèi)本身沒(méi)有實(shí)現(xiàn)+load方法,那么無(wú)論其各級(jí)超類(lèi)是否實(shí)現(xiàn)此方法系統(tǒng)都不會(huì)調(diào)動(dòng).這句話(huà)應(yīng)該這樣理解:正常我們給一個(gè)對(duì)象或者類(lèi)發(fā)消息,如果這個(gè)對(duì)象(或類(lèi))本身沒(méi)有實(shí)現(xiàn)該方法,那么系統(tǒng)會(huì)通過(guò)isa指針找到父類(lèi)的實(shí)現(xiàn).但是+load方法不同,子類(lèi)如果沒(méi)有實(shí)現(xiàn)該方法那么也不會(huì)去父類(lèi)中找.也就是說(shuō)你實(shí)現(xiàn)了系統(tǒng)就調(diào)用,你沒(méi)實(shí)現(xiàn)就算了.但是如果在+load中顯式的調(diào)用[super load];那么就會(huì)去調(diào)用父類(lèi)方法了.
//普通方法,子類(lèi)實(shí)現(xiàn)
@implementation FatherClass
- (void)eat {
NSLog(@"%s,%@",__func__,self);
}
@end
@implementation SonClass
- (void)eat {
NSLog(@"%s,%@",__func__,self);
}
@end
SonClass *son = [SonClass new];
[son eat];
輸出臺(tái):
//-[SonClass eat],<SonClass: 0x600000017970>

//子類(lèi)未實(shí)現(xiàn)
@implementation FatherClass
- (void)eat {
NSLog(@"%s,%@",__func__,self);
}
@en
@implementation SonClass
@end
SonClass *son = [SonClass new];
[son eat];
輸出臺(tái):
//-[FatherClass eat],<SonClass: 0x600000001600>

//+load方法,子類(lèi)實(shí)現(xiàn)
@implementation FatherClass
+(void)load {
NSLog(@"%s,%@",__func__,self);
}
@end
@implementation SonClass
+(void)load {
NSLog(@"%s,%@",__func__,self);

@end
輸出臺(tái):
//+[FatherClass load],FatherClass
//+[SonClass load],SonClass

//子類(lèi)未實(shí)現(xiàn)
@implementation FatherClass
+(void)load {
NSLog(@"%s,%@",__func__,self);
}
@end
@implementation SonClass
@end
輸出臺(tái):
//+[FatherClass load],FatherClass
  • 在+load方法中的實(shí)現(xiàn)務(wù)必精簡(jiǎn),盡量減少里面所執(zhí)行的操作,因?yàn)檎麄€(gè)應(yīng)用在執(zhí)行+load方法時(shí)都會(huì)阻塞,如果在+load中進(jìn)行繁雜的代碼,那么應(yīng)用程序在執(zhí)行期間就會(huì)變得無(wú)響應(yīng),不要調(diào)用可能會(huì)加鎖的方法.實(shí)際上但凡是通過(guò)+load方法實(shí)現(xiàn)的某些任務(wù),基本上都做得不對(duì),真正的用途僅在于調(diào)試程序,比如可以再分類(lèi)中實(shí)現(xiàn)+load來(lái)看該分類(lèi)是否已經(jīng)正確載入系統(tǒng)中.

+initialize

調(diào)用時(shí)機(jī)

對(duì)于每個(gè)類(lèi)來(lái)說(shuō),該方法會(huì)在程序第一次使用該類(lèi)或者該類(lèi)的子類(lèi)時(shí)被調(diào)用,并且只會(huì)調(diào)用一次.如果子類(lèi)沒(méi)有實(shí)現(xiàn),那么會(huì)調(diào)用父類(lèi)的該方法

//子類(lèi)實(shí)現(xiàn)
@implementation FatherClass
+ (void)initialize {
NSLog(@"%s,%@",__func__,self);
}
- (void)eat {
NSLog(@"%s,%@",__func__,self);
}
@end
@implementation SonClass
+ (void)initialize {
NSLog(@"%s,%@",__func__,self);
}
@end

SonClass *son = [SonClass new];
[son eat];
輸出臺(tái):
//+[FatherClass initialize],FatherClass
//+[SonClass initialize],SonClass

//子類(lèi)不實(shí)現(xiàn)
@implementation FatherClass
+ (void)initialize {
NSLog(@"%s,%@",__func__,self);
}
- (void)eat {
NSLog(@"%s,%@",__func__,self);
}
@end
@implementation SonClass
@end

SonClass *son = [SonClass new];
[son eat];
輸出臺(tái):
//+[FatherClass initialize],FatherClass
//+[FatherClass initialize],SonClass

我們發(fā)現(xiàn)子類(lèi)如果實(shí)現(xiàn)了就走子類(lèi)的方法,子類(lèi)沒(méi)有實(shí)現(xiàn)就走父類(lèi)的方法.這與普通的方法是相同的,都遵循集成規(guī)則,這個(gè)與+load不同.
那我們?nèi)绻幌胍驗(yàn)樽宇?lèi)而調(diào)用到父類(lèi)的方法該怎么辦呢?

@implementation FatherClass
+ (void)initialize {
if (self == [FatherClass class]) {
NSLog(@"%s,%@",__func__,self);
}
}
@end
輸出臺(tái)
//+[FatherClass initialize],FatherClass
+load與+initalize方法的區(qū)別
  • +initalize 是惰性調(diào)用,只有當(dāng)給該類(lèi)或者該類(lèi)的派生類(lèi)被使用時(shí)才會(huì)被調(diào)用.
  • +load方法,應(yīng)用會(huì)阻塞并等待所有類(lèi)的+load執(zhí)行完才會(huì)繼續(xù)執(zhí)行.
  • +initalize方法是線(xiàn)程安全的.所以不用擔(dān)心對(duì)該類(lèi)第一次發(fā)消息的線(xiàn)程問(wèn)題.
  • +load不遵循繼承規(guī)則
  • +load方法運(yùn)行環(huán)境不是安全的,但是+initalize方法運(yùn)行時(shí)可以調(diào)用任何類(lèi)的任何方法;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,734評(píng)論 18 399
  • 之前一直覺(jué)得很復(fù)雜,今天研究了下,其實(shí)不算復(fù)雜(不要怕麻煩),記住這幾點(diǎn)就夠了: load load就是類(lèi)的加載,...
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,068評(píng)論 0 9
  • load 和 initialize 兩個(gè)方法算是兩個(gè)特殊的類(lèi)方法了,今天偶然從草稿箱中看到還有本篇未完成的博文,如...
    RITL閱讀 1,652評(píng)論 8 13
  • 沖“老沒(méi)譜”(梅爾吉布森)去的,《勇敢的心》隔著液晶都把我感動(dòng)得糊涂,尤其受刑臨終一句“freedom”?。。?!老...
    某某文閱讀 213評(píng)論 0 0

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