靜態庫

一. 靜態庫的簡介

    • 所謂庫, 就是講程序代碼集合, 封裝為一個庫文件, 他是共享代碼的一種方式, 可以將自己的代碼共享給他人使用
  1. 庫的分類
    • 開源庫: 公開代碼, 能看到代碼的具體實現
    • 閉源庫:
      • 不公開代碼, 將代碼的實現編譯為二進制文件, 只將API接口提供給使用者
      • 閉源庫分為
        • 靜態庫: .a和.framework
        • 動態庫: .dylib和.framework
  2. 靜態庫和動態庫的區別
    1. 靜態庫在鏈接時, 會被完整的復制到可執行文件中; 多次使用, 就會有多次的拷貝;(import)
    2. 動態庫則不會復制, 只有一份, 當程序運行時動態加載到內存; 系統只加載一次, 多個程序可以共用, 節省內存
    3. 注意: 項目如果使用到自己的動態庫, 蘋果就不會上架你的APP
      • 但是, 在WWDC2014上公布的, 蘋果對iOS8開放動態加載dylib的接口, 也就是說開放了動態庫掛載
  3. 靜態庫的主要用途
    • 保護自己的代碼: 將自己的技術分享給其他人使用, 但是又不希望自己的代碼暴露給別人, 就可以使用靜態庫:
      • 如一些技術公司提供的SDK: 支付寶/百度高德地圖/推送等
    • 將MRC的項目, 打包成靜態庫, 可以直接在ARC的環境下直接使用, 不需要轉換

二. 靜態庫的制作

  1. 生成靜態庫的大致步驟:
    1. 創建一個項目, 在選擇工程文件時: iOS(Framework & Library) -> Cocoa Touch Static Library
    2. 選擇當生成靜態庫時, 要暴露給外人使用的頭文件
      • TARGETS(項目文件) -> Build Phases -> Copy Files -> 需要暴露的頭文件后面打鉤(Code Sign On Copy)
    3. 如果當前是模擬器環境, 編譯程序的話, 就會得到模擬器狀態下的靜態庫
    4. 如果當前是真機環境, 編譯程序就會得到真機狀態下的靜態庫
      • 編譯之后, 在項目工程文件處查看, 如果Products中的.a文件是紅色的, 代表創建失敗
      • 如果.a文件變為白色, 代表創建成功, 右擊Show In Finder就可以查看對應版本的靜態庫
        • Debug-iphoneos: 調試版本的真機靜態庫
        • Debug-iphonesimulator: 調試版本的模擬器靜態庫
        • Release-iphoneos: 發布版本的真機靜態庫
        • Release-iphonesimilator: 發布版本的模擬器靜態庫
    5. 生成的靜態庫一般包括兩個文件
      • include文件夾, 存放暴露出來的頭文件, 有各種屬性/方法的聲明
      • .a文件: 將實現文件編譯為二進制后生成的文件

三. 靜態庫使用測試

  1. 使用模擬器的靜態庫:(在6S, iOS9.2模擬器環境下生成的靜態庫)
    1. 模擬器和真機環境下的靜態庫不能共用
    2. 使用低版本的模擬器, 不能運行高版本模擬器下生成的靜態庫
  2. 靜態庫對應的CPU架構:
    1. 模擬器:
      • 4s---5: i386架構
      • 5s---6sPlus: x86_64架構
    2. 真機:
      • 4s: armv7
      • 5/5c: armv7s(但是他兼容armv7)
      • 5s---6sPlus: arm64
  3. 查看當前靜態庫支持的架構
    • 使用終端, 進入靜態庫.a文件所在的目錄
    • 使用命令: lipo -info .a文件名稱, 即可查看靜態庫所支持的系統架構
    • 經過檢查, 剛剛生成的靜態庫支持的架構為: i386和x86_64, 因此他是不支持真機運行的
    • 在不同的模擬器下進行編譯, 生成的靜態庫支持的架構也就不同
  4. 生成支持多個架構的靜態庫
    • 默認情況下, 需要選中不同的模擬器分別進行編譯, 才會生成支持對應架構的靜態庫, 然后再合并靜態庫
    • 如果要生成支持多個架構的靜態庫, 需要以下步驟:
      • 點擊TARGET項目工程文件 -> Build Settings -> Build Active -> NO
      • 該選項表示不知編譯活躍的架構(當前架構), 而是編譯所有的架構

四. 靜態庫文件的版本

  1. 調試版本:

    • Debug-iphoneos: 真機調試版本
    • Debug-iphonesimulator: 模擬器調試版本
    • 特點:
      • 調試版本會包含完整的符號信息, 方便調試
      • 調試版本不會代碼進行優化
  2. 發布版本:

    • Release-iphoneos: 真機發布版本
    • Release-iphoneSimulator: 模擬器發布版本
    • 特點:
      • 發布版本不包含完整的符號信息
      • 發布版本的代碼會進行優化
      • 發布版本的大小比調試版本略小
      • 在執行速度方面, 發布版本會更快一些, 但是效果也并不顯著
  3. 生成不同的版本:

    • 項目 -> Edit Scheme -> Run(info) -> Release/Debug分貝進行編譯
  4. 生成一個既支持模擬器又支持真機的靜態庫

    1. 由于靜態庫針對于模擬器和真機, 生成的靜態庫版本是不一樣的(為了不同的CPU架構), 因此無法同時運行
    2. 靜態庫的合并
      • 在終端, 使用lipo -info .a文件名稱的方法, 查看靜態庫的版本
      • 合并.a文件
        lipo -create Debug-iphoneos/libTools.a Debug-iphonesimulator/libTools.a -output libTools.a
      • 文件合并之后, 可以查看該靜態庫目前已經支持armv7 i386 x86_64 arm64
  5. 合并靜態庫的特點:

    • 合并后的靜態庫, 既可以在真機上調試, 也可以在模擬器上調試
    • 但是如果靜態庫太大, 合并打包之后靜態庫會很大, 影響App的大小, 因此很多第三方靜態庫都是區分版本的
    • 因此, 使用靜態庫的時候一定要注意靜態庫支持的版本
  6. 拆解指定架構的庫

    • 可以將合并后的靜態庫, 按照所需版本拆解出來
    • 終端命令: lipo -thin 架構名稱 .a路徑 -output 目標路徑

五. .framework靜態庫的制作

  1. 制作流程
    1. 新建項目: 選擇.framework靜態庫
    2. 編譯時, 設置編譯所有的架構
      • TARGET -> Build Setting -> Build Active -> NO
    3. 此時編譯的話, 默認產生的是動態庫, 因此要設置鏈接類型
      • TARGET -> Build Setting -> 搜索Mach-o Type -> 改為靜態庫(Static Library)

六. 靜態庫的簡單小結

  1. 靜態庫的完整打包步驟:

    • .a文件肯定是靜態庫
    • .framework文件more是動態庫, 需要轉換為靜態庫(Mach-o Type)
    • 確定靜態庫是否支持模擬器或者真機中的所有CPU架構(Build Active)
    • 提供的靜態庫一般應該為release版本(項目文件 -> Run -> info)
  2. .a和.framework靜態庫的區別

    • .a是一個純二進制文件, 而.framework文件除了二進制文件, 還可以包含一些資源文件
    • .a文件不能直接使用, 需要.h文件配合使用; 而.framework文件則可以直接使用
    • .a + .h + sourceFile(bundle文件) = .framework文件
    • 建議使用.framework文件
  3. 靜態庫開發中遇到的常見問題

    1. 一些靜態庫包含的資源文件可能與我們自己的資源文件重名
      • Xcode在編譯的時候, 會把所有的資源文件導入mainBundle中, 這樣可能出現重名沖突
      • 因此在靜態庫中使用圖片素材, 需要利用bundle文件
        • 建立一個bundle文件, 然后向其中添加靜態庫所需的圖片
        • 在庫中創建一個類方法, 返回圖片
        • 編譯
        • 外界如果需要使用圖片, 需要導入.h + .a + XXX.bundle文件
    2. 如果用戶需要導入的頭文件過多, 就可以使用一個主頭文件, 包含其他所有的頭文件, 這樣用戶只需要導入一個主頭文件就可以了
    3. 靜態庫程序怎樣測試
      • 靜態庫本身就是一個項目文件, 為了實現某些功能, 通常需要和項目一起進行測試, 才能查看是否達到了預期的效果
      • 因此可以使用復合項目的方法來解決
        • 直接在項目中, 創建一個.framework的文件
        • 正常設置庫文件應該做的設置
        • 配合項目工程來調試你的靜態庫
        • 最后設置打包靜態庫

七. 靜態庫的補充

  1. 將MRC的項目, 打包為靜態庫, 可以在ARC下直接使用, 不需要轉換
  2. Swift不支持靜態庫, 他只能使用靜態庫
    • 如果要想打包動態庫并且暴露API, 就需要在你需要暴露的方法前, 增加public關鍵字
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容