iOS 動態(tài)庫、靜態(tài)庫、framework

什么是庫

程序庫(library),一個可供使用的各種標(biāo)準(zhǔn)程序、子程序、文件以及它們的目錄等信息的有序集合。 匯集在一起的經(jīng)常應(yīng)用的程序。

簡單來說,庫(Library)就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別人使用。

為什么要用到庫

  1. 當(dāng)我們的代碼要提供給別人使用,我們又不希望用戶看到代碼的具體實(shí)現(xiàn)。就需要已庫的形式封裝,只暴露出頭文件。

  2. 對于某些不會進(jìn)行大的改動的代碼,想要減少編譯的時間,就可以把它打成庫,因?yàn)閹焓蔷幾g好的二進(jìn)制,編譯的時候只需要Link一下。節(jié)省時間。例如我們在做組件化的時期都會盡量做二進(jìn)制化,來提高M(jìn)erge編譯效率。

靜態(tài)庫

靜態(tài)庫即靜態(tài)鏈接庫(Windows下的.lib, Linux和Mac下的.a)。之所以叫靜態(tài)庫,是因?yàn)殪o態(tài)庫在編譯時候會被拷貝一份,復(fù)制到目標(biāo)程序里,復(fù)制到目標(biāo)程序里。這段代碼在目標(biāo)程序里就不會再改變了。

優(yōu)點(diǎn):

  1. 編譯完成之后,目標(biāo)程序就沒有外部依賴,直接就可以運(yùn)行。
  2. 提高目標(biāo)程序編譯效率。

缺點(diǎn):

  1. 增大目標(biāo)程序體積。

  2. 多次使用就會有多份冗余拷貝。(沙盒機(jī)制避免了多個目標(biāo)程序同時使用)

動態(tài)庫

動態(tài)庫即動態(tài)鏈接庫(Windows下的.dll, Linux下的.so,Mac下的.dylib/.tbd)。與靜態(tài)庫相反,動態(tài)庫在編譯時并不會被拷貝到目標(biāo)程序中,目標(biāo)程序中會存儲指向動態(tài)庫的引用。等到程序運(yùn)行時,動態(tài)庫才會被真正加載進(jìn)來。

優(yōu)點(diǎn):

  1. 不需要拷貝到目標(biāo)程序中,不會影響目標(biāo)程序體積,
  2. 同一個庫可以被多個程序使用(因?yàn)檫@個原因,動態(tài)庫也被稱為共享庫)。
  3. 運(yùn)行時才載入的特性,也可以讓我們隨時對庫進(jìn)行替換,而不需要重新編譯代碼。

缺點(diǎn):

  1. 動態(tài)載入會帶來一部分性能損失。
  2. 動態(tài)庫使得程序依賴外部環(huán)境,如果環(huán)境缺少動態(tài)庫或者庫版本不正確,導(dǎo)致程序無法運(yùn)行。

Framework

除了.a 和.dylib/.tbd,Mac OS/iOS 平臺還可以使用Framework。

Framework實(shí)際上是一種打包方式,將庫的二進(jìn)制文件,頭文件和有關(guān)的資源文件打包在一起。方便管理和分發(fā),和靜態(tài)動態(tài)庫的本質(zhì)沒有什么關(guān)系。

在iOS8之前,iOS平臺不支持使用動態(tài)Framework,開發(fā)者只可以使用系統(tǒng)的UIKit 、Foundation這些Framework。同時因?yàn)閕OS的沙盒機(jī)制,不同程序不能共享代碼,同時動態(tài)下載代碼是被蘋果命令禁止的,沒有辦法發(fā)揮出動態(tài)庫的優(yōu)勢。所以在iOS平臺共享代碼,唯一的選擇就是打成靜態(tài)庫.a文件,同時附上頭文件。

小結(jié):

  1. 動態(tài)庫類型: .a和.framework 靜態(tài)庫類型:dylib和.framework。 系統(tǒng)提供的Framework是動態(tài)的,自己創(chuàng)建的是靜態(tài)的。
  2. .a 是單純的二進(jìn)制文件,.framework是二進(jìn)制文件+資源文件。 .framework = .a + .h + sorrceFile(資源文件)
  3. 在iOS上共享代碼理論上只能使用靜態(tài)庫。

Embedded Framework

但是后來iOS8之后,iOS有了App Extesion特性,而且Swift也誕生了。由于iOS主App需要和Extension共享代碼,Swift語言機(jī)制也需要動態(tài)庫,于是蘋果后來提出了Embedded Framework,這種動態(tài)庫允許APP和APP Extension共享代碼,但是這份動態(tài)庫的生命被限定在一個APP進(jìn)程內(nèi)。簡單點(diǎn)可以理解為被閹割的動態(tài)庫。

但是這種動態(tài)庫(Embedded Framework) 和系統(tǒng)的 UIKit.Framework 還是有很大區(qū)別,傳統(tǒng)的動態(tài)庫是給多個進(jìn)程用的,而這里的動態(tài)庫(Embedded Framework)是給單個進(jìn)程里面多個可執(zhí)行文件用的。系統(tǒng)的 Framework 不需要拷貝到目標(biāo)程序中,我們自己做出來的 動態(tài)庫(Embedded Framework) 哪怕是動態(tài)的,最后也還是要拷貝到 App 中(App 和 Extension 的 Bundle 是共享的)。所以蘋果沒有直接把這種Embedded Framework稱作動態(tài)庫而是叫Embedded Framework。

上面提到跟Swift也有原因,在Swift的項目中如果要在項目中使用外部的代碼,可選的方式只有兩種,一種是把代碼拷貝到工程中,另一種是用動態(tài) Framework。使用靜態(tài)庫是不支持的。這個問題的根本原因主要是 Swift 的運(yùn)行庫沒有被包含在 iOS 系統(tǒng)中,而是會打包進(jìn) App 中(這也是造成 Swift App 體積大的原因),靜態(tài)庫會導(dǎo)致最終的目標(biāo)程序中包含重復(fù)的運(yùn)行庫

參考文獻(xiàn)

  1. iOS 中的動態(tài)庫、靜態(tài)庫和 framework
  2. iOS動態(tài)庫、靜態(tài)庫及使用場景、方式
  3. iOS制作Framework庫
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容