iOS類方法load和initialize詳解

+(void)load詳解

官方是這么定義+(void)load方法的

Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.

當類(Class)或者類別(Category)加入Runtime中時(就是被引用的時候)穷娱。
實現(xiàn)該方法,可以在加載時做一些類特有的操作娃承。

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.
調用所有的Framework中的初始化方法

All +load methods in your image.
調用所有的+load方法

All C++ static initializers and C/C++ attribute(constructor) functions in your image.
調用C++的靜態(tài)初始化方及C/C++中的attribute(constructor)函數(shù)

All initializers in frameworks that link to you.
調用所有鏈接到目標文件的framework中的初始化方法

In addition:

A class’s +load method is called after all of its superclasses’ +load methods.
一個類的+load方法在其父類的+load方法后調用

A category +load method is called after the class’s own +load method.
一個Category的+load方法在被其擴展的類的自有+load方法后調用

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.
在+load方法中,可以安全地向同一二進制包中的其它無關的類發(fā)送消息,但接收消息的類中的+load方法可能尚未被調用移必。

調用時機

+(void)load方法的加載和這個類是否被使用到無關,這也是為什么可以在ios端能夠做到無痕埋點的原因毡鉴。子類是否重寫父類的load方法和這個方法的調用無關崔泵,所以也就不需要在子類的方法里面調用父類方法,他的調用在init main方法之前,只會被調用一次且線程安全猪瞬。

  • 當父類和子類都實現(xiàn)load函數(shù)時,父類的load方法執(zhí)行順序要優(yōu)先于子類
  • 當子類未實現(xiàn)load方法時,不會調用父類load方法
  • 類中的load方法執(zhí)行順序要優(yōu)先于類別(Category)
  • 當有多個類別(Category)都實現(xiàn)了load方法,這幾個load方法都會執(zhí)行,但執(zhí)行順序不確定(其執(zhí)行順序與類別在Compile Sources中出現(xiàn)的順序一致)
  • 當然當有多個不同的類的時候,每個類load 執(zhí)行順序與其在Compile Sources出現(xiàn)的順序一致

運用

從上文的運行流程分析中已經(jīng)了解到憎瘸,main函數(shù)是整個應用運行的入口load方法是在main函數(shù)之前執(zhí)行的,并且只執(zhí)行一次撑螺,load方法既然這么特殊,那么在使用他時肯定還是要注意很多東西崎弃。

  • 不要做耗時操作
    因為執(zhí)行在main函數(shù)之前甘晤,所有是所有實現(xiàn)的load函數(shù)跑完了才會啟動應用,在load方法中進行耗時操作必然會影響程序的啟動時間饲做,這么一想load方法里寫耗時操作一聽就是大忌了线婚。比如下面的操作···
+ (void)load {
    for (NSInteger i = 0; i < 10000; i ++) {
        NSLog(@"%zd" , i);
    }
}
  • 不要做對象的初始化操作
    因為在main函數(shù)之前自動調用,load方法調用的時候使用者根本就不能確定自己要使用的對象是否已經(jīng)加載進來了盆均,所以千萬不能在這里初始化對象塞弊。

  • 常用場景 load方法中實現(xiàn)Method Swizzle
    Method Swizzing是發(fā)生在運行時的,主要用于在運行時將兩個Method進行交換泪姨,我們可以將Method Swizzling代碼寫到任何地方游沿,但是只有在這段Method Swilzzling代碼執(zhí)行完畢之后互換才起作用。

+ (void)load {
    Method originalFunc = class_getInstanceMethod([self class], @selector(originalFunc));
    Method swizzledFunc = class_getInstanceMethod([self class], @selector(swizzledFunc));
    method_exchangeImplementations(originalFunc, swizzledFunc);
}

在load方法中使用Method Swizzle 是一個常用場景肮砾。

注意:
load調用時機比較早,當load調用時,其他類可能還沒加載完成,運行環(huán)境不安全.
load方法是線程安全的诀黍,它使用了鎖,我們應該避免線程阻塞在load方法.

+(void)initialize:

initialize函數(shù)調用特點如下:

initialize在類或者其子類的第一個方法被調用前調用仗处。即使類文件被引用進項目,但是沒有使用,initialize不會被調用眯勾。由于是系統(tǒng)自動調用,也不需要再調用 [super initialize] 婆誓,否則父類的initialize會被多次執(zhí)行吃环。假如這個類放到代碼中,而這段代碼并沒有被執(zhí)行洋幻,這個函數(shù)是不會被執(zhí)行的郁轻。

  • 父類的initialize方法會比子類先執(zhí)行
  • 當子類未實現(xiàn)initialize方法時,會調用父類initialize方法,在此之前,父類的方法會被優(yōu)先調用一次;子類實現(xiàn)initialize方法時,會覆蓋父類initialize方法.
  • 當有多個Category都實現(xiàn)了initialize方法,會覆蓋類中的方法,只執(zhí)行一個(會執(zhí)行Compile Sources 列表中最后一個Category 的initialize方法)

注意:
在initialize方法收到調用時,運行環(huán)境基本健全文留。
initialize內部也使用了鎖范咨,所以是線程安全的故觅。但同時要避免阻塞線程,不要再使用鎖

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末渠啊,一起剝皮案震驚了整個濱河市输吏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌替蛉,老刑警劉巖贯溅,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異躲查,居然都是意外死亡它浅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門镣煮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姐霍,“玉大人,你說我怎么就攤上這事典唇∧髡郏” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵介衔,是天一觀的道長恨胚。 經(jīng)常有香客問我,道長炎咖,這世上最難降的妖魔是什么赃泡? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮乘盼,結果婚禮上升熊,老公的妹妹穿的比我還像新娘。我一直安慰自己绸栅,他們只是感情好僚碎,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阴幌,像睡著了一般勺阐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上矛双,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天渊抽,我揣著相機與錄音,去河邊找鬼议忽。 笑死懒闷,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播愤估,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼帮辟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了玩焰?” 一聲冷哼從身側響起由驹,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昔园,沒想到半個月后蔓榄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡默刚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年甥郑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荤西。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡澜搅,死狀恐怖,靈堂內的尸體忽然破棺而出邪锌,到底是詐尸還是另有隱情勉躺,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布秃流,位于F島的核電站赂蕴,受9級特大地震影響柳弄,放射性物質發(fā)生泄漏舶胀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一碧注、第九天 我趴在偏房一處隱蔽的房頂上張望嚣伐。 院中可真熱鬧,春花似錦萍丐、人聲如沸轩端。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽基茵。三九已至,卻和暖如春壳影,著一層夾襖步出監(jiān)牢的瞬間拱层,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工宴咧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留根灯,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像烙肺,于是被迫代替她去往敵國和親纳猪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內容