-
在main()函數(shù)之前,在一般情況下,我們都會將main()函數(shù)作為程序入口,在main函數(shù)之前,程序所經(jīng)歷的事情
image.png
- 靜態(tài)庫:鏈接時會被完整的復制到可執(zhí)行文件中,所以如果兩個程序都用了某個靜態(tài)庫,那么每個二進制文件中,都會包含這個靜態(tài)庫文件
- 動態(tài)庫:鏈接時不復制,在程序啟動后用動態(tài)加載,然后再決議符號,所以理論上動態(tài)庫只用存在一份,好多個程序都可以鏈接到這個動態(tài)庫上面,達到節(jié)省內存作用,還有另一個好處,由于動態(tài)庫并不綁定到可執(zhí)行程序上,所以我們想升級這個動態(tài)庫就很容易
動態(tài)鏈接庫
- iOS中用到的所有系統(tǒng)framework
- 加載OC runtime方法libobjc
-
系統(tǒng)級別的libSystem,例如libdispatch(GCD)和libSystem_blocks(Block)
這些放在內存中的共享庫文件會在app啟動后交給dyld動態(tài)鏈接器來進行鏈接管理,鏈接流程如下:
image.png
main()函數(shù)之前
- 首先加載load函數(shù)
- 加載dyld,dyld_start來實現(xiàn)加載
- main()函數(shù):加載共享系統(tǒng)動態(tài)庫,加載依賴的動態(tài)庫,鏈接動態(tài)庫,初始化主程序,返回主程序main()函數(shù)地址
- 加載共享緩存
- 生成ImageLoader對象
- 加載所有插入的庫loadInsertDylib
- 鏈接主程序
- 執(zhí)行初始化方法initializeMainExecutable
dyld加載順序
- __dyld_start(匯編)
- uintptr_t start()
- uintptr_t _main()
- 3.1.配置上下文
- 3.2.處理環(huán)境變量
- 3.3.加載共享緩存
- 3.4.將dyld加入UUID列表
- 3.5.加載所有image
3.5.1.為可執(zhí)行文件實例化imageLoader
3.5.2.為主可執(zhí)行文件創(chuàng)建image
3.5.3.加載任何插入動態(tài)庫
3.5.4.鏈接動態(tài)庫 - 3.6 初始化所有程序
3.6.1.遍歷初始化image
3.6.2.通知image初始化完成
3.6.3初始化libSystem
3.6.4.初始化libdispatch
3.6.5.初始化libobjc - 3.7進入主程序main函數(shù)

