Xcode_靜態庫 & 動態庫


  • 什么是 庫 ?
    庫就是程序代碼的集合, 將 N 個文件組織起來, 是共享程序代碼的一種方式。

  • 庫的分類?
    開源庫: 源碼是公開的, 可以看到每個實現文件 .m 的實現,
    例如 Github 上常用的開源庫 AFNetworking, SDWebImage 等.
    閉源庫: 不公開源碼, 是經過編譯后的二進制文件, 看不到具體的實現.
    閉源庫 又分為: 靜態庫 和 動態庫


  • 靜態庫的存在形式?
    .a
    .framework

  • 動態庫的存在形式?
    .dylib
    .framework ( 系統直接提供給我們的 framework 都是動態庫!)
    .tbd

  • 靜態庫的特點?
    .a + .h
    .a : 可以看做所有 .m 文件加密后的一個二進制文件
    .h : 頭文件, 用戶暴露可用的接口 (方法)

  • 理解:
    .a 是一個純二進制文件,
    .framework 中除了有二進制文件之外還有資源文件。
    .a 要有 .h 文件以及資源文件配合使用,
    .framework 文件 可以直接使用。
    總的來說,.a + .h + sourceFile = .framework。所以創建靜態庫最好還是用.framework的形式


  • 靜態庫 和 動態庫 的區別?
    .a 文件肯定是靜態庫,
    .dylib 肯定是動態庫,
    .framework 可能是靜態庫也可能是動態庫。

  • 不同點:
    1、靜態庫在鏈接時, 會被完整的賦值到可執行文件中, 如果多個 APP 都使用了同一個靜態庫, 那么每個 APP 都會拷貝一份, 缺點是浪費內存, 類似于定義一個基本變量, 使用該基本變量是新復制了一份數據, 而不是原來定義的
    2、動態庫不會復制, 只有一份, 程序運行時動態加載到內存中, 系統只會加載一次, 多個程序公用一份, 節約了內存. 類似于使用變量的內存地址一樣. 使用的是同一個變量
    3、但是項目中如果使用了自己定義的動態庫, 蘋果是不允許上架的, 在 iOS 8 后 蘋果開放了動態加載 .dylib 的接口, 用于掛載 .dylib 動態庫

  • 共同點:
    靜態庫和動態庫都是閉源庫,只能拿來滿足某個功能的使用,不會暴露內部具體的代碼信息


  • 靜態庫的運用場景?
    保護自己的核心代碼, 如訊飛語音摸索了好多年探索出的結果當然要保存起來, 都公開了公司怎么生存
    將 MRC 的項目打包成靜態庫, 可以在 ARC 下直接使用, 不用轉換, 如別人使用 MRC 寫的開源庫, 放到自己的 ARC 項目中, 需要對每個文件加一個編譯參數 -fno-objc-arc 這樣相對來說很麻煩, 將整個工程打包成 靜態庫 直接放到項目中即可, 也不用對每個文件添加編譯選項

iOS 開發中 靜態庫 & 動態庫 區別:

  • 靜態庫 & 動態庫 是相對 編譯期 和 運行期 的:
    靜態庫在程序編譯時會被鏈接到目標代碼中,程序運行時將不再需要改靜態庫;

  • 而動態庫在程序編譯時并不會被鏈接到目標代碼中,只是在程序運行時才被載入,因為在程序運行期間還需要動態庫的存在。

  • 從源代碼到 app ,當我們點擊了 build 之后,做了什么事情呢?
    預處理(Pre-process):把宏替換,刪除注釋,展開頭文件,產生 .i 文件。
    編譯(Compliling):把之前的 .i 文件轉換成匯編語言,產生 .s文件。
    匯編(Asembly):把匯編語言文件轉換為機器碼文件,產生 .o 文件。
    鏈接(Link):對.o文件中的對于其他的庫的引用的地方進行引用,生成最后的可執行文件(同時也包括多個 .o 文件進行 link)。


  • 靜態庫 好處:
    模塊化,分工合作,提高了代碼的復用及核心技術的保密程度
    避免少量改動經常導致大量的重復編譯連接
    也可以重用,注意不是共享使用

  • 動態庫 好處:
    使用動態庫,可以將最終可執行文件體積縮小,將整個應用程序分模塊,團隊合作,進行分工,影響比較小
    使用動態庫,多個應用程序共享內存中得同一份庫文件,節省資源
    使用動態庫,可以不重新編譯連接可執行程序的前提下,更新動態庫文件達到更新應用程序的目的。
    應用插件化
    軟件版本實時模塊升級
    在其它大部分平臺上,動態庫都可以用于不同應用間共享, 共享可執行文件,這就大大節省了內存。


  • 動態庫的處理方式
    首先,對于動態庫而言其實分 動態鏈接庫 和 動態加載庫 兩種的,這兩個最本質的區別還是加載時間。

  • 動態鏈接庫:在沒有被加載到內存的前提下,當可執行文件被加載,動態庫也隨著被加載到內存中。在 Linked Framework and Libraries 設置的一些 share libraries。【隨著程序啟動而啟動】

  • 動態加載庫:當需要的時候再使用 dlopen 等通過代碼或者命令的方式來加載。【在程序啟動之后】

  • 但是不論是哪種動態庫,相比較與靜態庫,動態庫處理起來要棘手的多。由于動態庫是動態的,所以你事先不知道某個函數的具體地址。因此動態鏈接器在鏈接函數的時候需要做大量的工作。


動態庫動態更新問題

能否動態庫的方式來動態更新AppStore上的版本呢?

framework 本來是蘋果專屬的內部提供的動態庫文件格式,但是自從 2014 年 WWDC 之后,開發者也可以自定義創建 framework 實現動態更新(繞過apple store審核,從服務器發布更新版本)的功能,這與蘋果限定的上架的 app 必須經過 apple store 的審核制度是沖突的,所以含有自定義的framework 的 app 是無法在商店上架的,但是如果開發的是企業內部應用,就可以考慮嘗試使用動態更新技術來將多個獨立的 app 或者功能模塊集成在一個 app 上面!(我開發的就是企業內部使用的 app,我們將企業官網中的板塊開發成4個獨立的app,然后將其改造為 framework 文件最終集成在一款平臺級的 app 當中進行使用,這樣就可以在一款 app 上面使用原本 4 個 app 的全部功能!)

使用自定義的動態庫的方式來動態更新只能用在 in house(企業發布) 和 develop 模式,卻但不能在使用到 AppStore ,因為在上傳打包的時候,蘋果會對我們的代碼進行一次 Code Singing,包括 app 可執行文件和所有 Embedded 的動態庫。因此,只要你修改了某個動態庫的代碼,并重新簽名,那么 MD5 的哈希值就會不一樣,在加載動態庫的時候,蘋果會檢驗這個 hash 值,當蘋果監測到這個動態庫非法時,就會造成 Crash

在制作 framework 的時候需要選擇這個 Mach-O Type.
為 Mach Object 文件格式的縮寫,它是一種用于可執行文件,目標代碼,動態庫,內核轉儲的文件格式。作為a.out格式的替代,Mach-O提供了更強的擴展性,并提升了符號表中信息的訪問速度。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

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