前言
做iOS的過程中會(huì)引用一些三方庫(kù),而這些庫(kù),有的是.a,有的是.framework,有的是.dylib,有的是.tbd,說實(shí)話,我還是比較暈的,做個(gè)筆記,方便記憶QAQ。
靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)
靜態(tài)庫(kù)(.a)和動(dòng)態(tài)庫(kù)(.dylib)都是編譯好的二進(jìn)制文件,區(qū)別在于用法。
對(duì)于一個(gè)靜態(tài)庫(kù)而言,其實(shí)已經(jīng)是編譯好的了,類似一個(gè) .o 的集合。在 build 的過程中只會(huì)參與鏈接的過程,而這個(gè)鏈接的過程簡(jiǎn)單的講就是合并,并且鏈接器只會(huì)將靜態(tài)庫(kù)中被使用的部分合并到可執(zhí)行文件中去,在編譯鏈接的時(shí)候,會(huì)將靜態(tài)庫(kù)的所有文件都添加到目標(biāo) app 可執(zhí)行文件中,并在程序運(yùn)行之后,靜態(tài)庫(kù)與 app 可執(zhí)行文件 一起被加載到同一塊代碼區(qū)中。
對(duì)于動(dòng)態(tài)庫(kù)而言,其實(shí)分 動(dòng)態(tài)鏈接庫(kù) 和 動(dòng)態(tài)加載庫(kù) 兩種的,這兩個(gè)最本質(zhì)的區(qū)別還是加載時(shí)間。
動(dòng)態(tài)鏈接庫(kù):在沒有被加載到內(nèi)存的前提下,當(dāng)可執(zhí)行文件被加載,動(dòng)態(tài)庫(kù)也隨著被加載到內(nèi)存中。
動(dòng)態(tài)加載庫(kù):當(dāng)需要的時(shí)候再使用 dlopen 等通過代碼或者命令的方式來加載。
但是不論是哪種動(dòng)態(tài)庫(kù),相比較與靜態(tài)庫(kù),動(dòng)態(tài)庫(kù)處理起來要棘手的多。由于動(dòng)態(tài)庫(kù)是動(dòng)態(tài)的,所以你事先不知道某個(gè)函數(shù)的具體地址。因此動(dòng)態(tài)鏈接器在鏈接函數(shù)的時(shí)候需要做大量的工作。
不管是靜態(tài)庫(kù)、動(dòng)態(tài)庫(kù),兩者的區(qū)別和在內(nèi)存哪個(gè)區(qū)域沒有關(guān)系,最本質(zhì)的區(qū)別是,一個(gè)的函數(shù)調(diào)用在編譯的時(shí)候就已經(jīng)確定,而動(dòng)態(tài)庫(kù)是動(dòng)態(tài)加載的。換句話說,靜態(tài)庫(kù)修改了東西,整個(gè)程序需要重新編譯,而對(duì)于動(dòng)態(tài)庫(kù)的修改而言,只需要重啟 app(重置 PLT )
注:
Mac下,.a文件指靜態(tài)庫(kù),.dylib指動(dòng)態(tài)庫(kù),.tbd其實(shí)是一個(gè)YAML文件,描述了需要鏈接的動(dòng)態(tài)庫(kù)的信息。主要目的是為了減少app 的下載大小,在xcode7以后用來取代.dylib。為了更方便的使用動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)(一般情況下,使用.a或者使用.tbd,都要配合資源文件和頭文件使用),所以我理解下來,『.framework = .a/.tbd + .h + bundle』
最后
其實(shí)關(guān)于Xcode怎么創(chuàng)建.framework,網(wǎng)上有很多教程,就不多說了,這篇文章都是參考了網(wǎng)上別人的說法,為了方便記憶和理解,才記錄下來的,其實(shí)說到動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的優(yōu)缺點(diǎn),說法很多,至于怎么選擇,還是看具體項(xiàng)目比較合適,目前我的認(rèn)識(shí)還很淺,如果有更好的理解了,再來更新,mark!!!QAQ
拓展
說到.a文件,關(guān)于.a文件的多平臺(tái)支持,還是需要研究一下的,這里先記錄下了,armv7 ,i386, x86_64 ,arm64,還有動(dòng)態(tài)庫(kù)實(shí)現(xiàn)app的熱修復(fù)(繼續(xù)學(xué)習(xí),我猜想JSPatch的思路應(yīng)該是這樣的)。