類方法load和initialize的區(qū)別,主類和分類有同名方法時(shí)的調(diào)用順序

本文主要分為兩部分, 第一部分是講解類方法load和initialize的區(qū)別; 第二部分是一些相關(guān)的面試題.

一. 類方法load和initialize的區(qū)別

Objective-C作為一門面向?qū)ο笳Z言吕朵,有類和對象的概念。編譯后了嚎,類相關(guān)的數(shù)據(jù)結(jié)構(gòu)會保留在目標(biāo)文件中碗殷,在運(yùn)行時(shí)得到解析和使用。在應(yīng)用程序運(yùn)行起來的時(shí)候挺份,類的信息會有加載和初始化過程。 就像Application有生命周期回調(diào)方法一樣贮懈,在Objective-C的類被加載和初始化的時(shí)候匀泊,也可以收到方法回調(diào)优训,可以在適當(dāng)?shù)那闆r下做一些定制處理。而這正是load和initialize方法可以幫我們做到的各聘。

@interface NSObject <NSObject> {

+ (void)load;
+ (void)initialize;

@end

1.1 load

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

官方解釋: 運(yùn)行時(shí)揣非,添加類或者分類的時(shí)候調(diào)用.

個(gè)人理解: +load方法在這個(gè)文件被程序裝載時(shí)調(diào)用.只要是在Compile Sources中出現(xiàn)的文件總是會被裝載,這與這個(gè)類是否被用到無關(guān)躲因,因此+load方法總是在main函數(shù)之前調(diào)用.

  1. 調(diào)用次數(shù)

因?yàn)?code>+load是runtime加載類早敬、分類的時(shí)候調(diào)用, 所以只會調(diào)用<math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mstyle mathcolor="red"><mn>1</mn></mstyle></mrow></semantics></math>1次.

  1. 調(diào)用方式

會循環(huán)調(diào)用所有類的+load方法. 注意,這里是(調(diào)用分類的+load方法也是如此)直接使用函數(shù)內(nèi)存地址的方式(*load_method)(cls, SEL_load)+load方法進(jìn)行調(diào)用的大脉,而不是使用發(fā)送消息objc_msgSend的方式搞监。

  1. 調(diào)用順序

+load方法加載順序:父類> 子類> 分類.

+load方法不會被覆蓋(比如有父類,子類镰矿,分類A琐驴,分類B,這四個(gè)load方法都會加載).

注意1:(如果分類中有A,B,順序要看A,B加入工程中順序) , 可能結(jié)果:( 父類> 子類> 分類A> 分類B ) 或者( 父類> 子類> 分類B> 分類A ).

注意2:分類中無父子關(guān)系, 依賴Compile Sources 的上下順序來調(diào)用秤标,上面的優(yōu)先調(diào)用.

1.2 initialize

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

+initialize方法是在類或它的子類收到第一條消息之前被調(diào)用的绝淡,這里所指的消息包括實(shí)例方法和類方法的調(diào)用,并且只會調(diào)用一次苍姜。initialize方法實(shí)際上是一種惰性調(diào)用牢酵,也就是說如果一個(gè)類一直沒被用到,那它的initialize方法也不會被調(diào)用怖现,這一點(diǎn)有利于節(jié)約資源.

  1. 調(diào)用次數(shù)

因?yàn)?code>+initialize自己沒有實(shí)現(xiàn)的情況下就會去找父類的, 所以調(diào)用次數(shù)不確定.

  1. 調(diào)用方式

runtime使用了發(fā)送消息objc_msgSend的方式對+initialize方法進(jìn)行調(diào)用茁帽。也就是說+initialize 方法的調(diào)用與普通方法的調(diào)用是一樣的,走的都是發(fā)送消息的流程屈嗤。換言之潘拨,如果子類沒有實(shí)現(xiàn)+initialize方法,那么繼承自父類的實(shí)現(xiàn)會被調(diào)用饶号;如果一個(gè)類的分類實(shí)現(xiàn)了+initialize方法铁追,那么就會對這個(gè)類中的實(shí)現(xiàn)造成覆蓋。

  1. 調(diào)用順序

1.當(dāng)調(diào)用子類的+initialize方法時(shí)候,先調(diào)用父類的,如果父類有分類, 那么分類的+initialize會覆蓋掉父類的. 2.分類的+initialize會覆蓋掉父類的 3.子類的+initialize不會覆蓋分類的 4.父類的+initialize不一定會調(diào)用, 因?yàn)橛锌赡芨割惖姆诸愔貙懥怂?/p>

  • eg1:當(dāng)工程中Person主類有initialize茫船,分類不存在initialize琅束,調(diào)用[Son new]結(jié)果如下:
+[Person initialize]
+[Son initialize]
  • eg2:當(dāng)工程中Person主類有或無initialize,分類存在initialize算谈,調(diào)用[Son new]結(jié)果如下:
+[Person(Ability) initialize]
+[Son initialize]
  • eg3:當(dāng)工程中Person主類有initialize涩禀,分類和子類不存在initialize,調(diào)用[Son new]結(jié)果如下:
+[Person initialize]
+[Person initialize]
  • eg4:當(dāng)工程中Person主類有或無initialize然眼,分類存在initialize, 子類不存在initialize艾船,調(diào)用[Son new]結(jié)果如下:
+[Person(Ability) initialize]
+[Person(Ability) initialize]
  1. 注意點(diǎn)
  • initialize的自然調(diào)用是在第一次主動(dòng)使用當(dāng)前類的時(shí)候.
  • 關(guān)于繼承:和load不同,即使子類不實(shí)現(xiàn)initialize方法,會把父類的實(shí)現(xiàn)繼承過來調(diào)用一遍屿岂,就是會沿用父類的+initialize.(沿用父類的方法中践宴,self還是指子類)
  • 父類和本類的調(diào)用:子類的+initialize將要調(diào)用時(shí)會激發(fā)父類調(diào)用的+initialize方法,所以也不需要在子類寫明[super initialize].
  • 多個(gè)分類就看Compile Sources的順序爷怀,只執(zhí)行一個(gè)Category的+initialize方法, 也就是<math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mstyle mathcolor="red"><mtext>最下面的那個(gè)分類</mtext></mstyle></mrow></semantics></math>最下面的那個(gè)分類)

1.3 總結(jié)

標(biāo)題 +load +initialize
調(diào)用時(shí)機(jī) 被添加到runtime時(shí) 收到第一條消息前, 也可能用于那也不會調(diào)用
調(diào)用順序 父類 > 本類 > 分類 父類 > 本類 (如果有分類就是分類最大)
若自身未實(shí)現(xiàn), 是否沿用父類方法
線程安全 安全 安全
類別中的定義 全部都會執(zhí)行, 但是灰分先后順序 不會全部執(zhí)行, 存在方法的覆蓋

注意:

  • 在使用時(shí)都不要過重地依賴于這兩個(gè)方法阻肩,除非真正必要。
  • 謹(jǐn)慎在分類中實(shí)現(xiàn)+initialize方法运授,因?yàn)槿绻诜诸愔袑?shí)現(xiàn)了烤惊,本類實(shí)現(xiàn)的+initialize方法將不會被調(diào)用。
  • 謹(jǐn)慎在分類中實(shí)現(xiàn)+load方法吁朦。因?yàn)槿绻诒绢愔袑?shí)現(xiàn)+load方法混淆A撕氧、B兩個(gè)方法,分類中也混淆A喇完、B,因?yàn)楸绢惡头诸惖?code>+load都實(shí)現(xiàn)了剥啤,所以都會調(diào)用锦溪,A、B在本類中置換后府怯,又在分類中置換了回來刻诊。
  • load方法通常用來進(jìn)行Method Swizzle,initialize方法一般用于初始化全局變量或靜態(tài)變量牺丙。
  • load和initialize方法內(nèi)部使用了鎖则涯,因此它們是線程安全的。實(shí)現(xiàn)時(shí)要盡可能保持簡單冲簿,避免阻塞線程粟判,不要再使用鎖。

二. 常見的相關(guān)面試題

2.1 主類和分類有同名方法時(shí)的調(diào)用順序

eg: 主類和分類有同名方法峦剔,分類會覆蓋主類的方法档礁。最后只保留一個(gè)同名方法
比如:主類Person和分類Person+A都有commonClsMethod類方法,執(zhí)行程序結(jié)果如下:

+[Person(A) commonClsMethod]

2.2 load/initialize需不需要在子類的實(shí)現(xiàn)中顯式地調(diào)用父類的實(shí)現(xiàn)

super的方法會成功調(diào)用吝沫,但是這是多余的呻澜,因?yàn)?code>runtime會自動(dòng)對父類的+load方法進(jìn)行調(diào)用,而+initialize則會隨子類自動(dòng)激發(fā)父類的方法不需要顯示調(diào)用惨险。另一方面羹幸,如果父類中的方法用到的self,其指代的依然是類自身辫愉,而不是父類栅受。

三. 結(jié)語

路漫漫其修遠(yuǎn)兮,吾將上下而求索~

作者簡書

作者掘金

作者GitHub

.End

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市窘疮,隨后出現(xiàn)的幾起案子袋哼,更是在濱河造成了極大的恐慌,老刑警劉巖闸衫,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涛贯,死亡現(xiàn)場離奇詭異,居然都是意外死亡蔚出,警方通過查閱死者的電腦和手機(jī)弟翘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骄酗,“玉大人稀余,你說我怎么就攤上這事∏鞣” “怎么了睛琳?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長踏烙。 經(jīng)常有香客問我师骗,道長,這世上最難降的妖魔是什么讨惩? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任辟癌,我火速辦了婚禮,結(jié)果婚禮上荐捻,老公的妹妹穿的比我還像新娘黍少。我一直安慰自己,他們只是感情好处面,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布厂置。 她就那樣靜靜地躺著,像睡著了一般鸳君。 火紅的嫁衣襯著肌膚如雪农渊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天或颊,我揣著相機(jī)與錄音砸紊,去河邊找鬼。 笑死囱挑,一個(gè)胖子當(dāng)著我的面吹牛醉顽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播平挑,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼游添,長吁一口氣:“原來是場噩夢啊……” “哼系草!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唆涝,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤找都,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后廊酣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體能耻,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年亡驰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晓猛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凡辱,死狀恐怖戒职,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情透乾,我是刑警寧澤洪燥,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站乳乌,受9級特大地震影響蚓曼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钦扭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望床绪。 院中可真熱鬧客情,春花似錦、人聲如沸癞己。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痹雅。三九已至仰担,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绩社,已是汗流浹背摔蓝。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留愉耙,地道東北人贮尉。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像朴沿,于是被迫代替她去往敵國和親猜谚。 傳聞我的和親對象是個(gè)殘疾皇子败砂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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