Xcode_靜態(tài)庫 & 動(dòng)態(tài)庫


  • 什么是 庫 ?
    庫就是程序代碼的集合, 將 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ò)展性,并提升了符號表中信息的訪問速度。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 靜態(tài)庫與動(dòng)態(tài)庫的區(qū)別 首先來看什么是庫,庫(Library)說白了就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別...
    吃瓜群眾呀閱讀 12,330評論 3 42
  • 僅以方便自己查閱記錄前言1.靜態(tài)庫和動(dòng)態(tài)庫有什么異同?靜態(tài)庫:鏈接時(shí)完整地拷貝至可執(zhí)行文件中,被多次使用就有多份冗...
    190CM閱讀 4,520評論 0 4
  • 前言 1.靜態(tài)庫和動(dòng)態(tài)庫有什么異同? 靜態(tài)庫:鏈接時(shí)完整地拷貝至可執(zhí)行文件中,被多次使用就有多份冗余拷貝。利用靜態(tài)...
    Ly夢k閱讀 8,749評論 3 18
  • 前段時(shí)間負(fù)責(zé)一個(gè)模塊,接手之前,看到其他組做類似模塊時(shí)沒日沒夜的加班,心里沒底,還好我接手的這個(gè)模塊比較簡單,雖然...
    RogueQ閱讀 158評論 0 0
  • 前兩天不知是涂的維A酸軟膏的副作用還是木瓜霜造成的過敏,頸部出現(xiàn)了一大片的閉合性粉刺,其中有一些還發(fā)展成又紅又腫的...
    Maggie燥與郁閱讀 353評論 0 0

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