一氯哮、 iOS 程序 main 函數(shù)之前發(fā)生了什么辙纬?
https://blog.sunnyxx.com/2014/08/30/objc-pre-main/
- 動(dòng)態(tài)鏈接庫(kù)
靜態(tài)鏈接的代碼在編譯的時(shí)候就已經(jīng)鏈接到程序中烈菌,運(yùn)行時(shí)直接執(zhí)行二進(jìn)制文件;而動(dòng)態(tài)鏈接庫(kù)需要在程序啟動(dòng)后才會(huì)動(dòng)態(tài)去鏈接這些動(dòng)態(tài)庫(kù)挂绰,這就是為什么在倒入動(dòng)態(tài)庫(kù)的時(shí)候我們會(huì)去設(shè)置 link binary with Libraries 選項(xiàng)抛腕。
有兩個(gè)默認(rèn)添加的 lib:libobjc 即 objc 和 runtime,libSystem 中包含了很多系統(tǒng)級(jí)別 lib肝劲,列幾個(gè)熟知的:
libdispatch ( GCD )
libsystem_c ( C語(yǔ)言庫(kù) )
libsystem_blocks ( Block )
libcommonCrypto ( 加密庫(kù)迁客,比如常用的 md5 函數(shù) )
這些 lib 都是dylib格式(如 windows 中的 dll ),系統(tǒng)使用動(dòng)態(tài)鏈接有幾點(diǎn)好處:
- 代碼共用:很多程序都動(dòng)態(tài)鏈接了這些 lib辞槐,但它們?cè)趦?nèi)存和磁盤中只有一份
- 易于維護(hù):由于被依賴的 lib 是程序執(zhí)行時(shí)才 link 的掷漱,所以這些 lib 很容易做更新,比如libSystem.dylib 是 libSystem.B.dylib 的替身榄檬,哪天想升級(jí)直接換成 libSystem.C.dylib 然后再替換替身就行了
- 減少可執(zhí)行文件體積:相比靜態(tài)鏈接卜范,動(dòng)態(tài)鏈接在編譯時(shí)不需要打進(jìn)去,所以可執(zhí)行文件的體積要小很多
- dyld
dyld(the dynamic link editor)鹿榜,Apple 的動(dòng)態(tài)鏈接器海雪,系統(tǒng) kernel 做好啟動(dòng)程序的初始準(zhǔn)備后,交給 dyld 負(fù)責(zé)犬缨,援引并翻譯《 Mike Ash 這篇 blog 》對(duì) dyld 作用順序的概括:
- 從 kernel 留下的原始調(diào)用棧引導(dǎo)和啟動(dòng)自己
- 將程序依賴的動(dòng)態(tài)鏈接庫(kù)遞歸加載進(jìn)內(nèi)存喳魏,當(dāng)然這里有緩存機(jī)制
- non-lazy 符號(hào)立即 link 到可執(zhí)行文件,lazy 的存表里
- Runs static initializers for the executable
- 找到可執(zhí)行文件的 main 函數(shù)怀薛,準(zhǔn)備參數(shù)并調(diào)用
- 程序執(zhí)行中負(fù)責(zé)綁定 lazy 符號(hào)刺彩、提供 runtime dynamic loading services、提供調(diào)試器接口
- 程序main函數(shù) return 后執(zhí)行 static terminator
- 某些場(chǎng)景下 main 函數(shù)結(jié)束后調(diào) libSystem 的 _exit 函數(shù)
二、Objective-C +load vs +initialize
http://blog.leichunfeng.com/blog/2015/05/02/objective-c-plus-load-vs-plus-initialize/
- +load方法
- 在加載類的時(shí)候被調(diào)用
- iOS應(yīng)用啟動(dòng)的時(shí)候创倔,回加載所有的類嗡害,就會(huì)調(diào)用每個(gè)類的這個(gè)方法
- 在mian函數(shù)之前每調(diào)用
三、 Objective-C Autorelease Pool 的實(shí)現(xiàn)原理
http://blog.leichunfeng.com/blog/2015/05/31/objective-c-autorelease-pool-implementation-principle/
https://blog.sunnyxx.com/2014/10/15/behind-autorelease/
四畦攘、 iOS自動(dòng)布局框架 - Masonry詳解
http://www.reibang.com/p/ea74b230c70d
五霸妹、 深入理解RunLoop
https://blog.ibireme.com/2015/05/18/runloop/
六、 iOS中__block 關(guān)鍵字的底層實(shí)現(xiàn)原理
七知押、 堆棧
http://www.reibang.com/p/746c747e7e00
八叹螟、大小端模式
為什么會(huì)有大小端模式之分呢?這是因?yàn)樵谟?jì)算機(jī)系統(tǒng)中台盯,我們是以字節(jié)為單位的罢绽,每個(gè)地址單元都對(duì)應(yīng)著一個(gè)字節(jié),一個(gè)字節(jié)為 8bit静盅。但是在C語(yǔ)言中除了8bit的char之外良价,還有16bit的short型,32bit的long型(要看具體的編譯器)蒿叠,另外明垢,對(duì)于位數(shù)大于 8位的處理器,例如16位或者32位的處理器市咽,由于寄存器寬度大于一個(gè)字節(jié)痊银,那么必然存在著一個(gè)如何將多個(gè)字節(jié)安排的問題。因此就導(dǎo)致了大端存儲(chǔ)模式和小端存儲(chǔ)模式魂务。例如一個(gè)16bit的short型x曼验,在內(nèi)存中的地址為0x0010,x的值為0x1122粘姜,那么0x11為高字節(jié)鬓照,0x22為低字節(jié)。對(duì)于 大端模式孤紧,就將0x11放在低地址中豺裆,即0x0010中,0x22放在高地址中号显,即0x0011中臭猜。小端模式,剛好相反押蚤。我們常用的X86結(jié)構(gòu)是小端模式蔑歌,而KEIL C51則為大端模式。很多的ARM揽碘,DSP都為小端模式次屠。有些ARM處理器還可以隨時(shí)在程序中(在ARM Cortex 系列使用REV园匹、REV16、REVSH指令 [1] )進(jìn)行大小端的切換劫灶。
大端模式:數(shù)據(jù)的高字節(jié)存放在低地址中裸违,數(shù)據(jù)的低字節(jié)存放在高地址中
小端模式:數(shù)據(jù)的低字節(jié)存放的高地址中,數(shù)據(jù)的高字節(jié)存放在低地址中