刨根問(wèn)底load initilze方法

首先了解一下應(yīng)用啟動(dòng)后,做了什么

main.m 中的 main() 是程序的入口,但在進(jìn)入 main 函數(shù)之前,程序就執(zhí)行了很多代碼(不然也不會(huì)啟動(dòng)那么久)。
將程序依賴的動(dòng)態(tài)鏈接庫(kù)加載進(jìn)內(nèi)存
加載可執(zhí)行文件中的所有符號(hào)、代碼
runtime 解析被編譯過(guò)的符號(hào)代碼,遍歷所有 Class,按繼承層級(jí)依次調(diào)用Class 的 load 方法和其 Category 的 load 方法。

詳細(xì)的步驟可以參考sunnyxx大神的這篇文章;

Load

Load方法在文件被程序裝載時(shí)調(diào)用.也就是在Compile Sources中出現(xiàn)的文件.與<em>這個(gè)類(lèi)是否被用到無(wú)關(guān)</em>.

調(diào)用規(guī)則

<pre>
2016-11-11 14:28:39.807 [1734:818024] +[FatherViewController load]
2016-11-11 14:28:39.808 [1734:818024] +[SonViewController load]
2016-11-11 14:28:39.808 [1734:818024] +[ViewController load]
2016-11-11 14:28:39.808 [1734:818024] +[AppDelegate load]
2016-11-11 14:28:39.808 [1734:818024] +[ClassMian load]

2016-11-11 14:28:39.809 [1734:818024] +[SonViewController(Category_son) load]
2016-11-11 14:28:39.809 [1734:818024] +[FatherViewController(Category_01) load]
2016-11-11 14:28:39.809 [1734:818024] +[ViewController(Category) load]
</pre>

如果感興趣 可以自己創(chuàng)建一些類(lèi)和類(lèi)別 展開(kāi) Build Phases 的 Compile Sources 調(diào)用下各個(gè)文件的順序 嘗試一下各種情況下load的調(diào)用順序.主要太沒(méi)技術(shù)含量了,就不詳細(xì)寫(xiě)這些了 = =.

結(jié)論

<ul>
<li> 執(zhí)行子類(lèi)的 load 之前,當(dāng)父類(lèi)未加載時(shí),先執(zhí)行父類(lèi)的 load 方法。</li>
<li>分類(lèi)的 load 方法統(tǒng)一在最后執(zhí)行</li>
<li>優(yōu)先滿足以上兩條,再滿足按 Compile Sources 的順序執(zhí)行 load 方法。</li></ul>

需要注意的是子類(lèi)如果沒(méi)有實(shí)現(xiàn)load方法,那么就不會(huì)調(diào)用父類(lèi)的load方法
由于調(diào)用load方法時(shí)的環(huán)境很不安全,我們應(yīng)該盡量減少load方法的邏輯。另一個(gè)原因是load方法是線程安全的,它內(nèi)部使用了鎖,所以我們應(yīng)該避免線程阻塞load方法中。

initialize

這個(gè)方法是在第一次給某個(gè)類(lèi)發(fā)送消息時(shí)調(diào)用(實(shí)例化對(duì)象),并且只會(huì)調(diào)用一次.這個(gè)類(lèi)方法是惰性調(diào)用,如果一個(gè)類(lèi)一直沒(méi)有被用到,此方法也不會(huì)執(zhí)行.

initiialze方法的執(zhí)行順序

<pre>**2016-11-11 15:19:18.029 [1850:1017547] +[FatherViewController load]** **2016-11-11 15:19:18.031 [1850:1017547] +[FatherViewController(Category_01) initialize]** **2016-11-11 15:19:18.031 [1850:1017547] +[SonViewController(Category_son) initialize]** **2016-11-11 15:19:18.031 [1850:1017547] +[SonViewController load]** **2016-11-11 15:19:18.031 [1850:1017547] +[ViewController load]** **2016-11-11 15:19:18.031 [1850:1017547] +[AppDelegate load]** **2016-11-11 15:19:18.031 [1850:1017547] +[mianClass load]** **2016-11-11 15:19:18.032 [1850:1017547] +[SonViewController(Category_son) load]** **2016-11-11 15:19:18.032 [1850:1017547] +[FatherViewController(Category_01) load]** **2016-11-11 15:19:18.032 [1850:1017547] +[ViewController(Category) load]** **2016-11-11 15:19:18.032 [1850:1017547] +[AppDelegate initialize]** **2016-11-11 15:19:18.085 [1850:1017547] +[ViewController(Category) initialize]**</pre>

從結(jié)果來(lái)看,先執(zhí)行了FatherViewController(Category_01) initialize, 在執(zhí)行了SonViewController(Category_son) initialize,而SonViewController load最后執(zhí)行.也就是說(shuō)load方法還未執(zhí)行也不會(huì)影響這個(gè)類(lèi)的使用.

下面來(lái)看一看initialize方法的繼承問(wèn)題

從上面打印結(jié)果可以看出執(zhí)行子類(lèi) initialize 的時(shí)候會(huì)先執(zhí)行其父類(lèi)的 initialize。且 category 的覆寫(xiě)效應(yīng)對(duì) load 方法無(wú)效,但對(duì) initialize 方法有效。下面將子類(lèi)的initialize注釋,重寫(xiě)其initialze方法

<pre>+ (void)initialize { NSLog(@"調(diào)用者:%@ 調(diào)用方法:%s",NSStringFromClass(self), __func__);}</pre>

子類(lèi)會(huì)繼承父類(lèi)的 initialize 。當(dāng)執(zhí)行完父類(lèi)的 initialize 方法,準(zhǔn)備執(zhí)行子類(lèi)的 initialize 方法時(shí),會(huì)根據(jù)繼承鏈找到父類(lèi)的 initialize 執(zhí)行。

什么時(shí)候使用initialize

initialize方法主要用于對(duì)一些不好方便在編譯期初始化的對(duì)象進(jìn)行賦值,如NSMutableArray的實(shí)例化方法,在使用此方法時(shí)需要注意此方法是被調(diào)用多次的 是否需要添加dispatch_once.

總結(jié)

1.loadinitialize方法都會(huì)在實(shí)例化對(duì)象前調(diào)用, 以main函數(shù)為分水嶺,load在mian之前,initialize在main之后.
2.loadinitialize方法調(diào)用父類(lèi)的方法是隱性的自動(dòng)調(diào)用,即使子類(lèi)沒(méi)有實(shí)現(xiàn)initialize方法也會(huì)調(diào)用父類(lèi)的方法,load方法則不會(huì)調(diào)用父類(lèi).
3.load方法常常用于黑魔法的實(shí)現(xiàn),initialize方法用于初始化全局變量
4.load initialize方法都是線程安全的!需避免復(fù)雜操作.

最后編輯于
?著作權(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)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • iOS開(kāi)發(fā)中總能看到+load和+initialize的身影,網(wǎng)上對(duì)于這兩個(gè)方法有很多解釋,官方也有說(shuō)明,但有些細(xì)...
    朱曉輝閱讀 27,675評(píng)論 19 139
  • load 和 initialize 兩個(gè)方法算是兩個(gè)特殊的類(lèi)方法了,今天偶然從草稿箱中看到還有本篇未完成的博文,如...
    RITL閱讀 1,631評(píng)論 8 13
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,030評(píng)論 0 9
  • 概述 Objective-C作為一門(mén)面向?qū)ο笳Z(yǔ)言,有類(lèi)和對(duì)象的概念。編譯后,類(lèi)相關(guān)的數(shù)據(jù)結(jié)構(gòu)會(huì)保留在目標(biāo)文件中,在...
    liuyanhongwl閱讀 4,977評(píng)論 1 42
  • Objective C類(lèi)方法load和initialize的區(qū)別過(guò)去兩個(gè)星期里,為了完成一個(gè)工作,接觸到了NSOb...
    亦晴工作室閱讀 1,434評(píng)論 0 10

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