靜態庫

1、靜態庫簡介程序員

1.一、庫:是程序代碼的集合,是共享程序代碼的一種方式。xcode

1.二、根據源代碼的公開狀況,庫能夠分爲2種類型架構

<1>、開源庫iphone

公開源代碼,能看到具體實現,好比咱們常見的:AFNetworking、SDWebImage、MJRefresh 等等測試

<2>、閉源庫優化

不公開源代碼,是通過編譯後的二進制文件,看不到具體實現ui

主要分爲:靜態庫、動態庫spa

1.三、靜態庫和動態庫的存在形式.net

  • 靜態庫:.a 和 .framework命令行

  • 動態庫:.dylib 和 .framework

1.四、靜態庫和動態庫在使用上的區別

靜態庫:連接時,靜態庫會被完整地複製到可執行文件中,被屢次使用就有多份冗餘拷貝(以下圖所示)

image.png

動態庫:連接時不復制,程序運行時由系統動態加載到內存,供程序調用,系統只加載一次,多個程序共用,節省內存(以下圖所示)

image.png

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

1.五、 靜態庫應用場景?

  • 保護本身的核心代碼,好比國內的環信,百度地圖,高德地圖,友盟,個推,他們掌握有核心技術,同時是又但願更多的程序員來使用其技術,所以採用"閉源"的方式開發使用,你只能看到他們的.h文件以及一些不重要的.m文件

  • 將 MRC 的項目,打包成靜態庫, 能夠在ARC下直接使用, 不須要轉換

1.六、靜態庫的特色?

  • 由 .a 和 .h 組成

  • 看不到具體實現的代碼

2、.a 靜態庫的製做

2.一、 建立項目時, 直接選擇靜態庫(.a)

image.png

建立項目時, 直接選擇靜態庫(`.a`)

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

image.png

定義一個類方法`+(void)jk_test`

2.三、添加暴露的文件

image.png

添加暴露的文件

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

image.png

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

image.png

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

2.五、新建一個工程測試 上面咱們建立的 .a 文件 與 暴露文件 是否可使用

image.png

新建一個工程測試 上面咱們建立的 `.a` 文件 與 暴露文件 是否可使用

測試結果:

一、使用6S模擬器進行測試, 可使用

二、使用低型號模擬器測試,; 失敗

三、使用真機, 編譯; 失敗

分析緣由:緣由是靜態庫分架構,不一樣的CPU架構是不同的 ,若是 .a靜態庫 不支持架構,運行會報錯

靜態庫所支持的架構

模擬器: 4s~5  : i386;5s ~ XS Max: x86_64

真機: 3gs~4s : armv7;5/5c : armv7s(armv7兼容armv7s);5s~XS Max: arm64: arm64

提示:上面的 i38六、x86_6四、armv七、armv7s、arm64 都是架構的名字

測試 .a靜態庫 所支持的架構:

1

2

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

lipo -info 庫文件

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

image.png

咱們以上面在模擬器下的 `.a靜態庫` 爲例

2.六、怎樣一次編譯支持多個架構的的靜態庫?

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

image.png

在 `Build Settings` ->` Build Active` ->` NO`

注意:你的xcode要有上面架構的機型,不然只會包含有的架構,若是沒有 i386架構,你能夠 下載 4s~5 模擬器,再重複上面的操做

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

debug(調試)版本

1

2

xcodebuild -target 要生成的靜態庫目名 -configuration Debug -sdk iphoneos -arch armv7 -arch arm64

xcodebuild -target 要生成的靜態庫目名 -configuration Debug -sdk iphonesimulator -arch i386 -arch x86_64

release(發佈)版本

1

2

xcodebuild -target 要生成的靜態庫目名 -configuration Release -sdk iphoneos -arch armv7 -arch arm64

xcodebuild -target 要生成的靜態庫目名 -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64

提示:咱們只須要生成發佈版本的就好,以下步驟

1

2

3

1、cd 進入靜態庫項目

cd 靜態庫項目

2、操做上面 release(發佈)版本 的命令

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

2.七、經過上面咱們能夠知道 .a靜態庫 在debug模式下的真機和模擬器編譯各會生成一個 .a靜態庫,在release模式下的真機和模擬器編譯也各會生成一個 .a靜態庫,那麼咱們給別人哪些 .a靜態庫用呢?

答案是:給其餘人在release模式下的:真機與模擬器下的.a靜態庫

提示:.a靜態庫 在 測試版本 與 發佈版本 的特色

  • Debug(調試版本):一、調試版本會包含完整的符號信息,以方便調試;二、調試版本不會對代碼進行優化

  • Release(發佈版本): 一、發佈版本不會包含完整的符號信息;二、發佈版本的執行代碼是進行過優化的;三、發佈版本的大小會比調試版本的略小;四、在執行速度方面,發佈版本會更快些,但不意味着會有顯著的提高

2.八、咱們給用戶發佈版本的兩個.a靜態庫(真機下的release模式下的.a靜態庫與模擬器release模式下的.a靜態庫),若是想要一個靜態庫, 既能夠在模擬器上運行, 也能夠在真機上運行怎麼作?

答案:把發佈版本的兩個.a靜態庫合成一個 .a靜態庫

合併步驟:

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

image.png

檢查發佈版本的兩個靜態庫是否支持的 架構都全

<2>、合併 .a

image.png

合併 `.a`

1

2

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靜態庫時必定注意版本

3、.framework 靜態庫的製做

3.一、建立項目時, 直接選擇.framework靜態庫

image.png

建立項目時, 直接選擇.framework靜態庫

3.二、建立一個繼承於NSObject的JKTest類,並寫一個類方法,把該類的.h文件暴露出來

image.png

建立一個繼承於`NSObject`的`JKTest`類,並寫一個類方法

image.png

把該類的.h文件暴露出來

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

image.png

修改支持的最低版本

image.png

修改 把`.framework`的庫由 動態 改成 靜態庫 

1

2

3

4

5

6

// 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

image.png

使用xcodebuild生成靜Release下模擬器的靜態庫

提示:你若是須要 Debug 下的靜態庫,參照 2.6 自行生成

3.四、測試一下是否能夠運行(提示:若是不把動態庫改成靜態庫會運行報錯,若是你想強行使用動態庫,那麼你就在:TARGETS->General->Embedded Binaries 添加你的庫)

image.png

測試OK

3.五、合併 .framework 靜態庫

image.png

合併靜態庫

1

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

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

4、總結

4.一、靜態庫打包的完整正確步驟

<1>、肯定是靜態庫

.a 的確定是靜態庫

.framework的須要設置連接類型,project -> Build Settings-> 搜索 Mach-o Type ; 改成靜態庫選擇 Static Library

image.png

`.framework`的須要設置連接類型

<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.二、.a靜態庫和.framework靜態庫的區別?

<1>、.a 是一個純二進制文件,  .framework中除了有二進制文件以外還有資源文件,.bundle就是資源文件

<2>、.a 文件不能直接使用, 至少要有.h文件的配合; .framework 文件能夠直接使用

<3>、.a + .h + sourceFile = .framework

<4>、建議使用 .framework

4.三、靜態庫開發中的常見問題

問題1: 有些第三方庫會使用到一些圖片素材,例如公司的logo,xib文件等,如何作?

答:建立一個.bundle文件,建立方式看 資源文件 .buldle 的添加第十。

問題2: 若是用戶須要導入的頭文件過多怎麼加?

答:在建立  .framework項目會默認生成一個 .h 文件,咱們能夠把其餘的 .h 文件導入 默認生成一個.h 文件 中

問題3: 靜態庫程序怎樣測試?

答:建立一個建立複合項目,看下面 4.4 建立的步驟

4.四、建立一個建立複合項目(符合工程的名字定義爲:複合項目)

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

image.png

在複合項目中添加一個`.framework`的靜態庫`JKTools`

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

image.png

建立一個`JKTest`類,建立一個類方法

image.png

把JKTest的`.h`放到建立靜態庫生成的`.h`文件裏面

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

image.png

修改JKTools支持的最低版本爲9.0,看本身項目了

image.png

設置爲靜態庫

image.png

修改 Build Settings ->Build Active ->NO,這樣編譯以後,debug真機下支持debug真機下全部的架構,debug模擬器下支持debug模擬器下全部的架構image.png

把須要暴露的文件放到Public裏面

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

image.png

在符合項目添加咱們的靜態庫依賴

<5>、測試

導入#import,調用下面的方法

1

[JKTest jk_test];

打印結果:

1

複合項目的測試

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

5、將MRC的項目,打包成靜態庫, 能夠在ARC下直接使用, 不須要轉換

5.一、應用場景

你找到一個功能是ARC項目下的,你想用,裏面有不少的類,你怎麼把他們搬到ARC項目下使用???

5.二、解決方案一(適用於類不太的狀況)

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

image.png

咱們模擬一個類JKTools,它是MRC下的項目

<2>、咱們把JKTools的.h與.m拖到ARC的工程下,報錯是確定的,咱們看下如何處理。以下圖image.png

在ARC圖中路徑找到MRC下的.m文件,雙擊輸入-fno-objc-arc

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

5.三、解決方案二(適用於MRC的類不少的狀況):把MRC下的類打包成靜態庫,.a 或者 .framework 均可以,下面以打包成.framework爲例,步驟以下

<1>、建立一個.framework項目,這裏名字一JKTools爲例,把上面JKTools.h和JKTools.m拖進去,把並修改項目爲 MRCimage.png

修改項目爲MRC

在TARGETS->Build Settings下搜 Automatic Reference ,改成 NO;其中YES爲ARC,NO爲MRC。

<2>、重複 4.4 裏面<3>的步驟

<3>、生成發佈版本的靜態庫以及合併真機與模擬器的二進制文件,最後把合併的二進制文件替換掉 真機下framework裏面的二進制文件

<4>、把framework拖入 ARC的項目,直接導入framework裏面的.h文件查看是否能夠,通過測試時OK的,不懂的你能夠聯繫我

5、Swift打包動態庫

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

image.png

建立一個`Swift` 下的 `.framework` 工程,命名爲 `JKTools` ,同時建立一個類`JKTest`,寫一個方法 `jk_test`

5.二、把支持的最低版本調爲 9.0,具體的看本身項目

image.png

把支持的最低版本調爲 9.0,具體的看本身項目

5.三、修改 Build Settings ->Build Active ->NO,這樣編譯以後,debug真機下支持debug真機下全部的架構,debug模擬器下支持debug模擬器下全部的架構

5.四、修改 爲靜態庫

image.png

修改 爲靜態庫

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

5.六、測試靜態庫的使用,結果顯示是OK的image.png

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

到此,靜態庫的相關知識記錄到這,相比較其餘的博客仍是比較詳細的。

相關文章
相關標籤/搜索