+ Load 和 +initalize

+ Load 和 +initalize 方法

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

+Load

調(diào)用時機

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

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

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

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

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

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


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

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

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

  • +load方法不像普通的方法那樣遵循繼承規(guī)則,如果一個類本身沒有實現(xiàn)+load方法,那么無論其各級超類是否實現(xiàn)此方法系統(tǒng)都不會調(diào)動.這句話應(yīng)該這樣理解:正常我們給一個對象或者類發(fā)消息,如果這個對象(或類)本身沒有實現(xiàn)該方法,那么系統(tǒng)會通過isa指針找到父類的實現(xiàn).但是+load方法不同,子類如果沒有實現(xiàn)該方法那么也不會去父類中找.也就是說你實現(xiàn)了系統(tǒng)就調(diào)用,你沒實現(xiàn)就算了.但是如果在+load中顯式的調(diào)用[super load];那么就會去調(diào)用父類方法了.
//普通方法,子類實現(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];
輸出臺:
//-[SonClass eat],<SonClass: 0x600000017970>

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

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

@end
輸出臺:
//+[FatherClass load],FatherClass
//+[SonClass load],SonClass

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

+initialize

調(diào)用時機

對于每個類來說,該方法會在程序第一次使用該類或者該類的子類時被調(diào)用,并且只會調(diào)用一次.如果子類沒有實現(xiàn),那么會調(diào)用父類的該方法

//子類實現(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];
輸出臺:
//+[FatherClass initialize],FatherClass
//+[SonClass initialize],SonClass

//子類不實現(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];
輸出臺:
//+[FatherClass initialize],FatherClass
//+[FatherClass initialize],SonClass

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

@implementation FatherClass
+ (void)initialize {
if (self == [FatherClass class]) {
NSLog(@"%s,%@",__func__,self);
}
}
@end
輸出臺
//+[FatherClass initialize],FatherClass
+load與+initalize方法的區(qū)別
  • +initalize 是惰性調(diào)用,只有當給該類或者該類的派生類被使用時才會被調(diào)用.
  • +load方法,應(yīng)用會阻塞并等待所有類的+load執(zhí)行完才會繼續(xù)執(zhí)行.
  • +initalize方法是線程安全的.所以不用擔心對該類第一次發(fā)消息的線程問題.
  • +load不遵循繼承規(guī)則
  • +load方法運行環(huán)境不是安全的,但是+initalize方法運行時可以調(diào)用任何類的任何方法;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摔蓝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子忠荞,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棺耍,死亡現(xiàn)場離奇詭異耕拷,居然都是意外死亡,警方通過查閱死者的電腦和手機萧求,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門其兴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人饭聚,你說我怎么就攤上這事忌警。” “怎么了秒梳?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵法绵,是天一觀的道長。 經(jīng)常有香客問我酪碘,道長朋譬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任兴垦,我火速辦了婚禮徙赢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘探越。我一直安慰自己狡赐,他們只是感情好,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布钦幔。 她就那樣靜靜地躺著枕屉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鲤氢。 梳的紋絲不亂的頭發(fā)上搀擂,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音卷玉,去河邊找鬼哨颂。 笑死,一個胖子當著我的面吹牛相种,可吹牛的內(nèi)容都是我干的威恼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼沃测!你這毒婦竟也來了缭黔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蒂破,失蹤者是張志新(化名)和其女友劉穎馏谨,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體附迷,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡惧互,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喇伯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喊儡。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖稻据,靈堂內(nèi)的尸體忽然破棺而出艾猜,到底是詐尸還是另有隱情,我是刑警寧澤捻悯,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布匆赃,位于F島的核電站,受9級特大地震影響今缚,放射性物質(zhì)發(fā)生泄漏算柳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一姓言、第九天 我趴在偏房一處隱蔽的房頂上張望瞬项。 院中可真熱鬧,春花似錦何荚、人聲如沸囱淋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妥衣。三九已至,卻和暖如春唠倦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涮较。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工稠鼻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狂票。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓候齿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子慌盯,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法周霉,類相關(guān)的語法,內(nèi)部類的語法亚皂,繼承相關(guān)的語法俱箱,異常的語法,線程的語...
    子非魚_t_閱讀 31,622評論 18 399
  • 之前一直覺得很復(fù)雜灭必,今天研究了下狞谱,其實不算復(fù)雜(不要怕麻煩),記住這幾點就夠了: load load就是類的加載禁漓,...
    改個假名穩(wěn)當點閱讀 313評論 1 0
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉跟衅,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評論 0 9
  • load 和 initialize 兩個方法算是兩個特殊的類方法了,今天偶然從草稿箱中看到還有本篇未完成的博文播歼,如...
    RITL閱讀 1,483評論 8 13
  • 沖“老沒譜”(梅爾吉布森)去的伶跷,《勇敢的心》隔著液晶都把我感動得糊涂,尤其受刑臨終一句“freedom”C啬0饶!谒撼!老...
    詩是一種存在方式閱讀 188評論 0 0