iOS 靜態庫

一、靜態庫簡介

  • 1.1、:是程序代碼的集合,是共享程序代碼的一種方式。

  • 1.2、根據源代碼的公開情況,庫可以分爲2種類型

    • <1>、開源庫
      公開源代碼,能看到具體實現,比如我們常見的:AFNetworking、SDWebImage、MJRefresh 等等
    • <2>、閉源庫
      不公開源代碼,是經過編譯後的二進制文件,看不到具體實現
      主要分爲:靜態庫動態庫
  • 1.3、靜態庫和動態庫的存在形式

    • 靜態庫:.a.framework
    • 動態庫:.dylib.framework
  • 1.4、靜態庫和動態庫在使用上的區別

    • 靜態庫:鏈接時,靜態庫會被完整地複製到可執行文件中,被多次使用就有多份冗餘拷貝(如下圖所示)
    • 動態庫:鏈接時不復制,程序運行時由系統動態加載到內存,供程序調用,系統只加載一次,多個程序共用,節省內存(如下圖所示)

      需要注意的是:項目中如果使用了自制的動態庫,不能被上傳到AppStore, 不允許上架!

  • 1.5、 靜態庫應用場景?

    • 保護自己的核心代碼,比如國內的環信,百度地圖,高德地圖,友盟,個推,他們掌握有核心技術,同時是又希望更多的程序員來使用其技術,因此採用"閉源"的方式開發使用,你只能看到他們的.h文件以及一些不重要的.m文件
    • MRC 的項目,打包成靜態庫, 可以在ARC下直接使用, 不需要轉換
  • 1.6、靜態庫的特點?

    • .a.h 組成
    • 看不到具體實現的代碼

二、.a 靜態庫的製作

  • 2.1、 創建項目時, 直接選擇靜態庫(.a)

  • 2.2、定義一個類方法+(void)jk_test,在.h裏面暴露出來jk_test

  • 2.3、添加暴露的文件

  • 2.4、分別在真機與6s下編譯,查看生成的.a與暴露文件


  • 2.5、新建一個工程測試 上面我們創建的 .a 文件 與 暴露文件 是否可以使用

    • 測試結果:

      • 1、使用6S模擬器進行測試, 可以使用
      • 2、使用低型號模擬器測試,; 失敗
      • 3、使用真機, 編譯; 失敗

    分析原因:原因是靜態庫分架構,不同的CPU架構是不一樣的 ,如果 .a靜態庫 不支持架構,運行會報錯

    • 靜態庫所支持的架構
    • 模擬器: 4s~5 : i386;5s ~ XS Max: x86_64
    • 真機: 3gs~4s : armv7;5/5c : armv7s(armv7兼容armv7s);5s~XS Max: arm64: arm64
      提示:上面的 i386、x86_64、armv7、armv7s、arm64 都是架構的名字
    • 測試 .a靜態庫 所支持的架構:

      cd 進入 .a靜態庫所在的文件夾
      lipo -info 庫文件
      

      我們以上面在模擬器下的 .a靜態庫 爲例,如下圖

  • 2.6、怎樣一次編譯支持多個架構的的靜態庫?

    • 解決方案:在 Build Settings ->Build Active ->NO,這樣設置之後,debug真機下支持debug真機下所有的架構,debug模擬器下支持debug模擬器下所有的架構,再重複上面的測試,在iPhone5或者iPhone4下就不會報錯了

      注意:你的xcode要有上面架構的機型,否則只會包含有的架構,如果沒有 i386架構,你可以 下載 4s~5 模擬器,再重複上面的操作

    • 解決方案:xcodebuild 命令行生成靜態庫參考博客

      • debug(調試)版本

        xcodebuild -target 要生成的靜態庫目名 -configuration Debug -sdk iphoneos -arch armv7 -arch arm64
        xcodebuild -target 要生成的靜態庫目名 -configuration Debug -sdk iphonesimulator -arch i386 -arch x86_64
        
      • release(發佈)版本

        xcodebuild -target 要生成的靜態庫目名 -configuration Release -sdk iphoneos -arch armv7 -arch arm64
        xcodebuild -target 要生成的靜態庫目名 -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64
        
      • 提示:我們只需要生成發佈版本的就好,如下步驟

        # 1、cd 進入靜態庫項目
        cd 靜態庫項目
        # 2、操作上面 release(發佈)版本 的命令
        

        注意:在使用過 xcodebuild ,再利用 lipo -info 靜態庫名檢測,響應的架構都支持

  • 2.7、通過上面我們可以知道 .a靜態庫 在debug模式下的真機和模擬器編譯各會生成一個 .a靜態庫,在release模式下的真機和模擬器編譯也各會生成一個 .a靜態庫,那麼我們給別人哪些 .a靜態庫用呢?
    答案是:給其他人在release模式下的:真機與模擬器下的.a靜態庫

    提示:.a靜態庫測試版本發佈版本特點

    • Debug(調試版本):1、調試版本會包含完整的符號信息,以方便調試;2、調試版本不會對代碼進行優化
    • Release(發佈版本): 1、發佈版本不會包含完整的符號信息;2、發佈版本的執行代碼是進行過優化的;3、發佈版本的大小會比調試版本的略小;4、在執行速度方面,發佈版本會更快些,但不意味着會有顯著的提升
  • 2.8、我們給用戶發佈版本的兩個.a靜態庫(真機下的release模式下的.a靜態庫與模擬器release模式下的.a靜態庫),如果想要一個靜態庫, 既可以在模擬器上運行, 也可以在真機上運行怎麼做?
    答案:把發佈版本的兩個.a靜態庫合成一個 .a靜態庫😆

    • 合併步驟:
      • <1>、檢查發佈版本的兩個靜態庫是否支持的 架構都全


      • <2>、合併 .a

        cd 進入 Products 文件夾
        lipo -create  Release-iphoneos/libJKOCProjectTool.a  Release-iphonesimulator/libJKOCProjectTool.a  -output NewJKOCProjectTool.a
        

        提示:NewJKOCProjectTool.a 是生成的新的 .a,合成的.a的大小是合成前兩個.a大小的和

      • <3>、合成後的.a靜態庫的特點

        • (1)、合併.a好處,開發過程中既可以在真機上調試,也可以在模擬器上調試
        • (2)、 合併.a壞處,如果靜態庫太大,合併打包後,會非常大,因此很多第三方的靜態庫的.a是區分版本的

        提示:今後在使用.a靜態庫時一定注意版本

三、.framework 靜態庫的製作

  • 3.1、創建項目時, 直接選擇.framework靜態庫

  • 3.2、創建一個繼承於NSObjectJKTest類,並寫一個類方法,把該類的.h文件暴露出來


  • 3.3、利用上面2.6方案二生成發佈版本的靜態庫,記得修改支持的最低版本,修改 把.framework的庫由動態庫改爲靜態庫


    // 1.cd 進入靜態庫項目
    cd JKOCProjectTool
    // 2.使用xcodebuild生成靜Release下真機的靜態庫
    xcodebuild -target JKOCProjectTool -configuration Release -sdk iphoneos -arch armv7 -arch arm64
    // 3.使用xcodebuild生成靜Release下模擬器的靜態庫
    xcodebuild -target JKOCProjectTool -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64
    

    提示:你如果需要 Debug 下的靜態庫,參照 2.6 自行生成

  • 3.4、測試一下是否可以運行(提示:如果不把動態庫改爲靜態庫會運行報錯,如果你想強行使用動態庫,那麼你就在:TARGETS->General->Embedded Binaries 添加你的庫)

  • 3.5、合併 .framework 靜態庫

    lipo -create 真機的JKOCProjectTools路徑 模擬器的JKOCProjectTools路徑 -output 合併後的JKOCProjectTools文件
    

    切記:合成的是二進制文件而不是framework,最後合成的二進制文件替代之前的二進制文件即可

四、總結

  • 4.1、靜態庫打包的完整正確步驟

    • <1>、確定是靜態庫
      • .a 的肯定是靜態庫
      • .framework的需要設置鏈接類型,project -> Build Settings-> 搜索 Mach-o Type ; 改爲靜態庫選擇 Static Library
    • <2>、確定支持模擬器或者真機中的所有架構
      • 如果使用的2.6類裏面的 方案一 那就是xcode要支持所有的架構的模擬器,並且修改 Build Settings ->Build Active ->NO,這樣編譯之後,debug真機下支持debug真機下所有的架構,debug模擬器下支持debug模擬器下所有的架構
      • 如果使用的2.6類裏面的 方案二 xcodebuild方法就可以支持所有的架構
    • <3>、提供的靜態庫應該是 release版本
      • 如果使用的2.6類裏面的 方案一:項目 -> Edit Scheme -> Run -> Release/Debug 分別進行編譯
      • 如果使用的2.6類裏面的 方案二 xcodebuild方法,在命令類裏面輸入 Release 就好
  • 4.2、.a靜態庫.framework靜態庫的區別?

    • <1>、.a 是一個純二進制文件, .framework中除了有二進制文件之外還有資源文件,.bundle就是資源文件
    • <2>、.a 文件不能直接使用, 至少要有.h文件的配合; .framework 文件可以直接使用
    • <3>、.a + .h + sourceFile = .framework
    • <4>、建議使用 .framework
  • 4.3、靜態庫開發中的常見問題

    • 問題1: 有些第三方庫會使用到一些圖片素材,例如公司的logo,xib文件等,如何做?
      答:創建一個.bundle文件,創建方式看 資源文件 .buldle 的添加第十。
    • 問題2: 如果用戶需要導入的頭文件過多怎麼加?
      答:在創建 .framework項目會默認生成一個 .h 文件,我們可以把其他的 .h 文件導入 默認生成一個.h 文件 中
    • 問題3: 靜態庫程序怎樣測試?
      答:創建一個創建複合項目,看下面 4.4 創建的步驟
  • 4.4、創建一個創建複合項目(符合工程的名字定義爲:複合項目

    • <1>、在複合項目中添加一個.framework的靜態庫JKTools

    • <2>、創建一個JKTest類,創建一個類方法,並把JKTest的.h放到創建靜態庫生成的.h文件裏面


    • <3>、選中JKTools,修改下面選項




    • <4>、在符合項目添加我們的靜態庫依賴


    • <5>、測試
      導入#import <JKTools/JKTools.h>,調用下面的方法

      [JKTest jk_test];
      

      打印結果:

      複合項目的測試
      
    • <6>、有關 .framework的文件導出,我就不再重複了,也就是上面2.6的步驟,有關合上面也有講述

五、將MRC的項目,打包成靜態庫, 可以在ARC下直接使用, 不需要轉換

  • 5.1、應用場景
    你找到一個功能是ARC項目下的,你想用,裏面有很多的類,你怎麼把他們搬到ARC項目下使用???

  • 5.2、解決方案一(適用於類不太的情況)

    • <1>、我們模擬一個類JKTools,它是MRC下的項目


    • <2>、我們把JKTools的.h與.m拖到ARC的工程下,報錯是肯定的,我們看下如何處理。如下圖


    提示:在ARC圖中路徑找到MRC下的.m文件,雙擊輸入-fno-objc-arc,再運行就不會報錯了

  • 5.3、解決方案二(適用於MRC的類很多的情況):把MRC下的類打包成靜態庫,.a 或者 .framework 都可以,下面以打包成.framework爲例,步驟如下

    • <1>、創建一個.framework項目,這裏名字一JKTools爲例,把上面JKTools.hJKTools.m拖進去,把並修改項目爲 MRC

      TARGETS->Build Settings下搜 Automatic Reference ,改爲 NO;其中YES爲ARC,NO爲MRC。
    • <2>、重複 4.4 裏面 <3> 的步驟
    • <3>、生成發佈版本的靜態庫以及合併真機與模擬器的二進制文件,最後把合併的二進制文件替換掉 真機下framework裏面的二進制文件
    • <4>、把framework拖入 ARC的項目,直接導入framework裏面的.h文件查看是否可以,經過測試時OK的,不懂的你可以聯繫我

    五、Swift打包動態庫

    • 5.1、創建一個Swift 下的 .framework 工程,命名爲 JKTools ,同時創建一個類JKTest,寫一個方法 jk_test

    • 5.2、把支持的最低版本調爲 9.0,具體的看自己項目


    • 5.3、修改 Build Settings ->Build Active ->NO,這樣編譯之後,debug真機下支持debug真機下所有的架構,debug模擬器下支持debug模擬器下所有的架構

    • 5.4、修改 爲靜態庫


    • 5.5、在release下編譯模擬器與真機,生成像一個的.framework 文件,把類裏面的二進制文件合併成一個,步驟和上面一樣,不再重複了

    • 5.6、測試靜態庫的使用,結果顯示是OK的


到此,靜態庫的相關知識記錄到這,相比較其他的博客還是比較詳細的。遇到任何問題都可以再我的個人信息裏面來聯繫我

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章