什么是 庫 ?
庫就是程序代碼的集合, 將 N 個(gè)文件組織起來, 是共享程序代碼的一種方式。庫的分類?
開源庫: 源碼是公開的, 可以看到每個(gè)實(shí)現(xiàn)文件 .m 的實(shí)現(xiàn),
例如 Github 上常用的開源庫 AFNetworking, SDWebImage 等.
閉源庫: 不公開源碼, 是經(jīng)過編譯后的二進(jìn)制文件, 看不到具體的實(shí)現(xiàn).
閉源庫 又分為: 靜態(tài)庫 和 動(dòng)態(tài)庫
靜態(tài)庫的存在形式?
.a
.framework動(dòng)態(tài)庫的存在形式?
.dylib
.framework ( 系統(tǒng)直接提供給我們的 framework 都是動(dòng)態(tài)庫?。?br> .tbd靜態(tài)庫的特點(diǎn)?
.a + .h
.a : 可以看做所有 .m 文件加密后的一個(gè)二進(jìn)制文件
.h : 頭文件, 用戶暴露可用的接口 (方法)理解:
.a 是一個(gè)純二進(jìn)制文件,
.framework 中除了有二進(jìn)制文件之外還有資源文件。
.a 要有 .h 文件以及資源文件配合使用,
.framework 文件 可以直接使用。
總的來說,.a + .h + sourceFile = .framework。所以創(chuàng)建靜態(tài)庫最好還是用.framework的形式
靜態(tài)庫 和 動(dòng)態(tài)庫 的區(qū)別?
.a 文件肯定是靜態(tài)庫,
.dylib 肯定是動(dòng)態(tài)庫,
.framework 可能是靜態(tài)庫也可能是動(dòng)態(tài)庫。不同點(diǎn):
1、靜態(tài)庫在鏈接時(shí), 會被完整的賦值到可執(zhí)行文件中, 如果多個(gè) APP 都使用了同一個(gè)靜態(tài)庫, 那么每個(gè) APP 都會拷貝一份, 缺點(diǎn)是浪費(fèi)內(nèi)存, 類似于定義一個(gè)基本變量, 使用該基本變量是新復(fù)制了一份數(shù)據(jù), 而不是原來定義的
2、動(dòng)態(tài)庫不會復(fù)制, 只有一份, 程序運(yùn)行時(shí)動(dòng)態(tài)加載到內(nèi)存中, 系統(tǒng)只會加載一次, 多個(gè)程序公用一份, 節(jié)約了內(nèi)存. 類似于使用變量的內(nèi)存地址一樣. 使用的是同一個(gè)變量
3、但是項(xiàng)目中如果使用了自己定義的動(dòng)態(tài)庫, 蘋果是不允許上架的, 在 iOS 8 后 蘋果開放了動(dòng)態(tài)加載 .dylib 的接口, 用于掛載 .dylib 動(dòng)態(tài)庫共同點(diǎn):
靜態(tài)庫和動(dòng)態(tài)庫都是閉源庫,只能拿來滿足某個(gè)功能的使用,不會暴露內(nèi)部具體的代碼信息
- 靜態(tài)庫的運(yùn)用場景?
保護(hù)自己的核心代碼, 如訊飛語音摸索了好多年探索出的結(jié)果當(dāng)然要保存起來, 都公開了公司怎么生存
將 MRC 的項(xiàng)目打包成靜態(tài)庫, 可以在 ARC 下直接使用, 不用轉(zhuǎn)換, 如別人使用 MRC 寫的開源庫, 放到自己的 ARC 項(xiàng)目中, 需要對每個(gè)文件加一個(gè)編譯參數(shù) -fno-objc-arc 這樣相對來說很麻煩, 將整個(gè)工程打包成 靜態(tài)庫 直接放到項(xiàng)目中即可, 也不用對每個(gè)文件添加編譯選項(xiàng)
iOS 開發(fā)中 靜態(tài)庫 & 動(dòng)態(tài)庫 區(qū)別:
靜態(tài)庫 & 動(dòng)態(tài)庫 是相對 編譯期 和 運(yùn)行期 的:
靜態(tài)庫在程序編譯時(shí)會被鏈接到目標(biāo)代碼中,程序運(yùn)行時(shí)將不再需要改靜態(tài)庫;而動(dòng)態(tài)庫在程序編譯時(shí)并不會被鏈接到目標(biāo)代碼中,只是在程序運(yùn)行時(shí)才被載入,因?yàn)樵诔绦蜻\(yùn)行期間還需要?jiǎng)討B(tài)庫的存在。
從源代碼到 app ,當(dāng)我們點(diǎn)擊了 build 之后,做了什么事情呢?
預(yù)處理(Pre-process):把宏替換,刪除注釋,展開頭文件,產(chǎn)生 .i 文件。
編譯(Compliling):把之前的 .i 文件轉(zhuǎn)換成匯編語言,產(chǎn)生 .s文件。
匯編(Asembly):把匯編語言文件轉(zhuǎn)換為機(jī)器碼文件,產(chǎn)生 .o 文件。
鏈接(Link):對.o文件中的對于其他的庫的引用的地方進(jìn)行引用,生成最后的可執(zhí)行文件(同時(shí)也包括多個(gè) .o 文件進(jìn)行 link)。
靜態(tài)庫 好處:
模塊化,分工合作,提高了代碼的復(fù)用及核心技術(shù)的保密程度
避免少量改動(dòng)經(jīng)常導(dǎo)致大量的重復(fù)編譯連接
也可以重用,注意不是共享使用動(dòng)態(tài)庫 好處:
使用動(dòng)態(tài)庫,可以將最終可執(zhí)行文件體積縮小,將整個(gè)應(yīng)用程序分模塊,團(tuán)隊(duì)合作,進(jìn)行分工,影響比較小
使用動(dòng)態(tài)庫,多個(gè)應(yīng)用程序共享內(nèi)存中得同一份庫文件,節(jié)省資源
使用動(dòng)態(tài)庫,可以不重新編譯連接可執(zhí)行程序的前提下,更新動(dòng)態(tài)庫文件達(dá)到更新應(yīng)用程序的目的。
應(yīng)用插件化
軟件版本實(shí)時(shí)模塊升級
在其它大部分平臺上,動(dòng)態(tài)庫都可以用于不同應(yīng)用間共享, 共享可執(zhí)行文件,這就大大節(jié)省了內(nèi)存。
動(dòng)態(tài)庫的處理方式
首先,對于動(dòng)態(tài)庫而言其實(shí)分 動(dòng)態(tài)鏈接庫 和 動(dòng)態(tài)加載庫 兩種的,這兩個(gè)最本質(zhì)的區(qū)別還是加載時(shí)間。動(dòng)態(tài)鏈接庫:在沒有被加載到內(nèi)存的前提下,當(dāng)可執(zhí)行文件被加載,動(dòng)態(tài)庫也隨著被加載到內(nèi)存中。在 Linked Framework and Libraries 設(shè)置的一些 share libraries?!倦S著程序啟動(dòng)而啟動(dòng)】
動(dòng)態(tài)加載庫:當(dāng)需要的時(shí)候再使用 dlopen 等通過代碼或者命令的方式來加載。【在程序啟動(dòng)之后】
但是不論是哪種動(dòng)態(tài)庫,相比較與靜態(tài)庫,動(dòng)態(tài)庫處理起來要棘手的多。由于動(dòng)態(tài)庫是動(dòng)態(tài)的,所以你事先不知道某個(gè)函數(shù)的具體地址。因此動(dòng)態(tài)鏈接器在鏈接函數(shù)的時(shí)候需要做大量的工作。
動(dòng)態(tài)庫動(dòng)態(tài)更新問題
能否動(dòng)態(tài)庫的方式來動(dòng)態(tài)更新AppStore上的版本呢?
framework 本來是蘋果專屬的內(nèi)部提供的動(dòng)態(tài)庫文件格式,但是自從 2014 年 WWDC 之后,開發(fā)者也可以自定義創(chuàng)建 framework 實(shí)現(xiàn)動(dòng)態(tài)更新(繞過apple store審核,從服務(wù)器發(fā)布更新版本)的功能,這與蘋果限定的上架的 app 必須經(jīng)過 apple store 的審核制度是沖突的,所以含有自定義的framework 的 app 是無法在商店上架的,但是如果開發(fā)的是企業(yè)內(nèi)部應(yīng)用,就可以考慮嘗試使用動(dòng)態(tài)更新技術(shù)來將多個(gè)獨(dú)立的 app 或者功能模塊集成在一個(gè) app 上面!(我開發(fā)的就是企業(yè)內(nèi)部使用的 app,我們將企業(yè)官網(wǎng)中的板塊開發(fā)成4個(gè)獨(dú)立的app,然后將其改造為 framework 文件最終集成在一款平臺級的 app 當(dāng)中進(jìn)行使用,這樣就可以在一款 app 上面使用原本 4 個(gè) app 的全部功能?。?/p>
使用自定義的動(dòng)態(tài)庫的方式來動(dòng)態(tài)更新只能用在 in house(企業(yè)發(fā)布) 和 develop 模式,卻但不能在使用到 AppStore ,因?yàn)樵谏蟼鞔虬臅r(shí)候,蘋果會對我們的代碼進(jìn)行一次 Code Singing,包括 app 可執(zhí)行文件和所有 Embedded 的動(dòng)態(tài)庫。因此,只要你修改了某個(gè)動(dòng)態(tài)庫的代碼,并重新簽名,那么 MD5 的哈希值就會不一樣,在加載動(dòng)態(tài)庫的時(shí)候,蘋果會檢驗(yàn)這個(gè) hash 值,當(dāng)蘋果監(jiān)測到這個(gè)動(dòng)態(tài)庫非法時(shí),就會造成 Crash
在制作 framework 的時(shí)候需要選擇這個(gè) Mach-O Type.
為 Mach Object 文件格式的縮寫,它是一種用于可執(zhí)行文件,目標(biāo)代碼,動(dòng)態(tài)庫,內(nèi)核轉(zhuǎn)儲的文件格式。作為a.out格式的替代,Mach-O提供了更強(qiáng)的擴(kuò)展性,并提升了符號表中信息的訪問速度。