學習筆記:Objective-C load 與 initialize 方法

簡介

在前東家的工作項目中匾南,遇到過使用 +load 進行 Method Swizzling 相關配置的情況啃匿,當時大概查了下 +load 方法的特點和用法,也沒有太在意蛆楞;后來看資料發(fā)現(xiàn)還有個 +initialize 方法溯乒,與 +load 有相似之處但區(qū)別也很大,于是趁當下有閑暇時間豹爹,系統(tǒng)閱覽文檔后寫下學習筆記裆悄,以作日后回顧參考。

共同點

看過官方文檔以及別人的博客后覺得帅戒,它們共同點不大灯帮,若是從使用角度去看,可以認為都可以用作類的初始化設定逻住。但由于兩者的調(diào)用次數(shù)和調(diào)用時機乃至調(diào)用時的外部環(huán)境(如其他類是否已初始化)都有區(qū)別钟哥,因此使用場景需加以區(qū)分。

調(diào)用時序

+load

+load 是應用開始運行瞎访,對應類(class)或者類別(category)被加載到 runtime 時調(diào)用腻贰,而且早在 main 函數(shù)被調(diào)用前。而且在每次加載扒秸,不同類的 +load 調(diào)用順序是不確定的播演,因此方法里的代碼不能依賴于某個其他類的 +load 調(diào)用。除此之外伴奥,其特點可以歸結為以下:

  • 只被調(diào)用一次写烤。
  • 如果項目中有父類,子類以及類別拾徙,并且每個文件中都實現(xiàn)了 +load洲炊,其調(diào)用順序為:父類 -> 子類 -> 父類類別 -> 子類類別
  • 如果父類實現(xiàn)了 +load 而子類沒有實現(xiàn),父類的 +load 也會被調(diào)用暂衡,因為子類被 runtime 加載理所當然地需要父類被加載询微。因此我們不需要也不應該調(diào)用 [super load]

+initialize

懶加載是 +initialize+load 很大的一個區(qū)別狂巢。它的懶是在該類在應用中第一次接收消息前(如第一次調(diào)用 [Class alloc])才被調(diào)用撑毛。如果該類在項目中沒使用過,就永遠不會被調(diào)用唧领。其特點歸結如下:

  • 可能會被調(diào)用不止一次藻雌。會被多次調(diào)用的情況有兩種:
    1. 子類沒有實現(xiàn) +initialize,同時在項目中子類第一次接收消息比父類的早時疹吃;
    2. 子類調(diào)用 [super initialize]

為了避免方法內(nèi)代碼被多次調(diào)用蹦疑,蘋果文檔建議檢查方法調(diào)用時類的類型:

+ (void)initialize {
  if (self == [ClassName self]) {
    // ... do the initialization ...
  }
}
  • 調(diào)用順序:父類 -> 子類
  • 線程安全。例如父類在線程A處在 +initialize 方法執(zhí)行中萨驶,子類在線程B觸發(fā)父類的 +initialize 時需要等待線程A的執(zhí)行完才會執(zhí)行歉摧。因為會導致線程阻塞,方法里不應該執(zhí)行復雜耗時的操作腔呜。

例子

通過代碼例子能跟直觀地了解二者的特性與調(diào)用時序:

// headers
// 父類
@interface Animal : NSObject
@end

// 子類
@interface Bird : NSObject
@end

// 父類類別
@interface Animal (Talkable)
@end

// 子類類別
@interface Bird (Talkable)
@end

//********** 分隔線 **********//

// implementation
// 父類
@implementation Animal
+ (void)load
{
    NSLog(@"Animal load called");
}

+ (void)initialize
{
    NSLog(@"Animal initialize called");
}
@end

// 子類
@implementation Bird
+ (void)load
{
    NSLog(@"Bird load called");
}

+ (void)initialize
{
    NSLog(@"Bird initialize called");
}
@end

// 父類類別
@implementation Animal (Talkable)
+ (void)load
{
    NSLog(@"Animal category load called");
}
@end

// 子類類別
@implementation Bird (Talkable)
+ (void)load
{
    NSLog(@"Bird category load called");
}
@end

然后在項目某個地方調(diào)用叁温,例如在 application:didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    Bird *bird = [[Bird alloc] init];
    Animal *animal = [[Animal alloc] init];
    
    return YES;
}

運行應用后控制臺輸出:

Animal load called
Bird load called
Animal category load called
Bird category load called
Animal initialize called
Bird initialize called

要驗證其他情況,在子類調(diào)用 super 以及調(diào)整下對象創(chuàng)建順序即可核畴,這里不再贅述膝但。

小結

兩者對比之下,+load 的使用場景比 +initialize 更加廣泛谤草。因為只被調(diào)用一次的特性跟束,而且調(diào)用時機早,+load 很適合進行 Method Swizzling 的操作丑孩。詳細源代碼實現(xiàn)冀宴,可在參考中查閱。

參考

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末略贮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仗岖,更是在濱河造成了極大的恐慌逃延,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轧拄,死亡現(xiàn)場離奇詭異揽祥,居然都是意外死亡,警方通過查閱死者的電腦和手機檩电,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進店門拄丰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桅打,“玉大人,你說我怎么就攤上這事愈案。” “怎么了鹅搪?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵站绪,是天一觀的道長。 經(jīng)常有香客問我丽柿,道長恢准,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任甫题,我火速辦了婚禮馁筐,結果婚禮上,老公的妹妹穿的比我還像新娘坠非。我一直安慰自己敏沉,他們只是感情好,可當我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布炎码。 她就那樣靜靜地躺著盟迟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪潦闲。 梳的紋絲不亂的頭發(fā)上攒菠,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音歉闰,去河邊找鬼辖众。 笑死,一個胖子當著我的面吹牛和敬,可吹牛的內(nèi)容都是我干的凹炸。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼概龄,長吁一口氣:“原來是場噩夢啊……” “哼还惠!你這毒婦竟也來了?” 一聲冷哼從身側響起私杜,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤蚕键,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后衰粹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锣光,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年铝耻,在試婚紗的時候發(fā)現(xiàn)自己被綠了誊爹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹬刷。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖频丘,靈堂內(nèi)的尸體忽然破棺而出办成,到底是詐尸還是另有隱情,我是刑警寧澤搂漠,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布迂卢,位于F島的核電站,受9級特大地震影響桐汤,放射性物質(zhì)發(fā)生泄漏而克。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一怔毛、第九天 我趴在偏房一處隱蔽的房頂上張望员萍。 院中可真熱鬧,春花似錦拣度、人聲如沸碎绎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽混卵。三九已至,卻和暖如春窖张,著一層夾襖步出監(jiān)牢的瞬間幕随,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工宿接, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赘淮,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓睦霎,卻偏偏與公主長得像梢卸,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子副女,可洞房花燭夜當晚...
    茶點故事閱讀 45,860評論 2 361

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