1卧斟、APP啟動時間
1)main之前的系統(tǒng)dylib(動態(tài)鏈接庫)和自身App可執(zhí)行文件的加載的時間
2)main之后執(zhí)行didFinishLaunchingWithOptions:結(jié)束前的時間
2亿鲜、main之前的加載過程
1)首先加載可執(zhí)行文件(自身app的所有.o文件集合)
2)然后加載動態(tài)鏈接庫dyld烙心,dyld是一個專門用來加載動態(tài)鏈接庫的庫
3)執(zhí)行從dyld開始腿箩,dyld從可執(zhí)行文件的依賴開始,遞歸加載所有的依賴動態(tài)鏈接庫
4)動態(tài)鏈接庫包括:iOS中用到的所有系統(tǒng)的framework栈暇,加載OC runtime方法的libobjec脾猛,系統(tǒng)級別的libSystem,例如libdispatch(GCD)he libsystem_blocks(Block)
5)dyld:the dynamic link editor,所有動態(tài)鏈接庫和我們App的靜態(tài)庫.a和所有類文件編譯后.o文件,最終都由dyld加載到內(nèi)存的
3贤姆、動態(tài)鏈接庫庫是相對于系統(tǒng)來講的
4榆苞、可執(zhí)行文件是相對于App本身來講的
5、每個app 都是以鏡像為單位進行加載的
1)鏡像(Mirroring)是冗余的一種類型霞捡,一個磁盤上的數(shù)據(jù)在另一個磁盤上存在一個完全相同的副本即為鏡像语稠。
2)鏡像是一種文件存儲形式,可以把許多文件做成一個鏡像文件弄砍。
3)每個鏡像又都有個ImageLoader類來負責加載仙畦,一一對應(yīng)的關(guān)系
6、framework 是動態(tài)鏈接庫和相應(yīng)資源包含在一起的一個文件結(jié)構(gòu)
7音婶、系統(tǒng)使用動態(tài)鏈接庫的好處
1)代碼共用:很多程序都動態(tài)鏈接了這些lib慨畸,但它們在內(nèi)存和磁盤中只有一份
2)易于維護:由于被依賴的lib是程序執(zhí)行時才鏈接的,所以這些很容易更新衣式,只要保證在程序執(zhí)行之前寸士,獲取最新lib即可
3)減少可執(zhí)行文件體積:相比靜態(tài)鏈接檐什,動態(tài)鏈接在編譯時不需要打進去,所有可執(zhí)行文件的體積要小很多
8弱卡、動態(tài)鏈接庫的加載步驟具體分為5步
1)load dylibs image 讀取庫鏡像文件
2)Rebase image 重定位鏡像
3)Bind image 組裝鏡像
4)Objc setup 設(shè)置對象
5)initializers 初始化
9乃正、第一步又分為下面6個過程
1)分析所依賴的動態(tài)庫
2)找到動態(tài)庫的mach-o 文件(我們知道Windows下的文件都是PE文件,同樣在OS X和iOS中可執(zhí)行文件是Mach-o格式的婶博。)
3)打開文件
4)驗證文件
5)在系統(tǒng)核心注冊文件簽名
6)對動態(tài)庫的每一個segment調(diào)用mmap()
10瓮具、8.2,8.3
由于ASLR(address apace layout randomization)的存在凡人,可執(zhí)行文件和動態(tài)鏈接庫在虛擬內(nèi)存中的加載地址每次啟動都不固定名党,所以需要這兩步倆修復鏡像中的資源地址,來紙箱正確的地址
1)rabase 修復的是指當前鏡像內(nèi)存的資源指針挠轴;bind指向的是鏡像外部的資源指針
2)rebase步驟先進行传睹,需要把鏡像讀入內(nèi)存,并以page為單位進行加密驗證岸晦,保證不會被篡改欧啤;bind 在其后進行,由于要查詢表符號表启上,來指向鏡像的資源堂油;
11、8.4
- 注冊objc類
2)把category的定義插入方法列表
3)保證每個selector唯一
12碧绞、8.5
0)以上三步屬于靜態(tài)調(diào)整(fix up),都是在修改__DATA segment中內(nèi)容吱窝,從這里開始動態(tài)調(diào)整讥邻,開始在堆和堆棧寫入內(nèi)容
1)objc 的 + load 函數(shù)
2)C++的構(gòu)造函數(shù)屬性函數(shù) 形如 attribute((contructor))void DoSomeInitializationWork()
3)非基本類型的C++靜態(tài)全局變量的創(chuàng)建(通常是類或結(jié)構(gòu)體)(non-trivial initializer)重大初始化
13、再次回顧整個調(diào)用順序
1)dyld 開始將程序二進制文件初始化
2)交由ImageLoader 讀取 image院峡,其中包含了我們的類兴使,方法等各種符號(Class、Protocol 照激、Selector发魄、 IMP)
3)由于runtime 向dyld 綁定了回調(diào),當image加載到內(nèi)存后俩垃,dyld會通知runtime進行處理
4)runtime 接手后調(diào)用map_images做解析和處理
5)接下來load_images 中調(diào)用call_load_methods方法励幼,遍歷所有加載進來的Class,按繼承層次依次調(diào)用Class的+load和其他Category的+load方法
6)至此 所有的信息都被加載到內(nèi)存中
7)最后dyld調(diào)用真正的main函數(shù)
8)注意:dyld會緩存上一次把信息加載內(nèi)存的緩存口柳,所以第二次比第一次啟動快一點
簡單的回答:
1.動態(tài)庫鏈接庫
2.ImageLoader加載可執(zhí)行文件, 里邊是被編譯過的符號,代碼等
3.runtime與+load