1、靜態庫簡介程序員
1.一、庫:是程序代碼的集合,是共享程序代碼的一種方式。xcode
1.二、根據源代碼的公開狀況,庫能夠分爲2種類型架構
<1>、開源庫iphone
公開源代碼,能看到具體實現,好比咱們常見的:AFNetworking、SDWebImage、MJRefresh 等等測試
<2>、閉源庫優化
不公開源代碼,是通過編譯後的二進制文件,看不到具體實現ui
主要分爲:靜態庫、動態庫spa
1.三、靜態庫和動態庫的存在形式.net
靜態庫:.a 和 .framework命令行
動態庫:.dylib 和 .framework
1.四、靜態庫和動態庫在使用上的區別
靜態庫:連接時,靜態庫會被完整地複製到可執行文件中,被屢次使用就有多份冗餘拷貝(以下圖所示)
動態庫:連接時不復制,程序運行時由系統動態加載到內存,供程序調用,系統只加載一次,多個程序共用,節省內存(以下圖所示)
須要注意的是:項目中若是使用了自制的動態庫,不能被上傳到AppStore, 不容許上架!
1.五、 靜態庫應用場景?
保護本身的核心代碼,好比國內的環信,百度地圖,高德地圖,友盟,個推,他們掌握有核心技術,同時是又但願更多的程序員來使用其技術,所以採用"閉源"的方式開發使用,你只能看到他們的.h文件以及一些不重要的.m文件
將 MRC 的項目,打包成靜態庫, 能夠在ARC下直接使用, 不須要轉換
1.六、靜態庫的特色?
由 .a 和 .h 組成
看不到具體實現的代碼
2、.a 靜態庫的製做
2.一、 建立項目時, 直接選擇靜態庫(.a)
建立項目時, 直接選擇靜態庫(`.a`)
2.二、定義一個類方法+(void)jk_test,在.h裏面暴露出來jk_test
定義一個類方法`+(void)jk_test`
2.三、添加暴露的文件
添加暴露的文件
2.四、分別在真機與6s下編譯,查看生成的.a與暴露文件
分別在真機與6s下編譯,查看生成的.a與暴露文件
分別在真機與6s下編譯,查看生成的.a與暴露文件
2.五、新建一個工程測試 上面咱們建立的 .a 文件 與 暴露文件 是否可使用
新建一個工程測試 上面咱們建立的 `.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 |
|
咱們以上面在模擬器下的 .a靜態庫 爲例,以下圖
咱們以上面在模擬器下的 `.a靜態庫` 爲例
2.六、怎樣一次編譯支持多個架構的的靜態庫?
解決方案一:在 Build Settings ->Build Active ->NO,這樣設置以後,debug真機下支持debug真機下全部的架構,debug模擬器下支持debug模擬器下全部的架構,再重複上面的測試,在iPhone5或者iPhone4下就不會報錯了
在 `Build Settings` ->` Build Active` ->` NO`
注意:你的xcode要有上面架構的機型,不然只會包含有的架構,若是沒有 i386架構,你能夠 下載 4s~5 模擬器,再重複上面的操做
解決方案二:xcodebuild 命令行生成靜態庫參考博客
debug(調試)版本
1 2 |
|
release(發佈)版本
1 2 |
|
提示:咱們只須要生成發佈版本的就好,以下步驟
1 2 3 |
|
注意:在使用過 xcodebuild ,再利用 lipo -info 靜態庫名檢測,響應的架構都支持
2.七、經過上面咱們能夠知道 .a靜態庫 在debug模式下的真機和模擬器編譯各會生成一個 .a靜態庫,在release模式下的真機和模擬器編譯也各會生成一個 .a靜態庫,那麼咱們給別人哪些 .a靜態庫用呢?
答案是:給其餘人在release模式下的:真機與模擬器下的.a靜態庫
提示:.a靜態庫 在 測試版本 與 發佈版本 的特色
Debug(調試版本):一、調試版本會包含完整的符號信息,以方便調試;二、調試版本不會對代碼進行優化
Release(發佈版本): 一、發佈版本不會包含完整的符號信息;二、發佈版本的執行代碼是進行過優化的;三、發佈版本的大小會比調試版本的略小;四、在執行速度方面,發佈版本會更快些,但不意味着會有顯著的提高
2.八、咱們給用戶發佈版本的兩個.a靜態庫(真機下的release模式下的.a靜態庫與模擬器release模式下的.a靜態庫),若是想要一個靜態庫, 既能夠在模擬器上運行, 也能夠在真機上運行怎麼作?
答案:把發佈版本的兩個.a靜態庫合成一個 .a靜態庫
合併步驟:
<1>、檢查發佈版本的兩個靜態庫是否支持的 架構都全
檢查發佈版本的兩個靜態庫是否支持的 架構都全
<2>、合併 .a
合併 `.a`
1 2 |
|
提示:NewJKOCProjectTool.a 是生成的新的 .a,合成的.a的大小是合成前兩個.a大小的和
<3>、合成後的.a靜態庫的特色
(1)、合併.a的好處,開發過程當中既能夠在真機上調試,也能夠在模擬器上調試
(2)、 合併.a的壞處,若是靜態庫太大,合併打包後,會很是大,所以不少第三方的靜態庫的.a是區分版本的
提示:從此在使用.a靜態庫時必定注意版本
3、.framework 靜態庫的製做
3.一、建立項目時, 直接選擇.framework靜態庫
建立項目時, 直接選擇.framework靜態庫
3.二、建立一個繼承於NSObject的JKTest類,並寫一個類方法,把該類的.h文件暴露出來
建立一個繼承於`NSObject`的`JKTest`類,並寫一個類方法
把該類的.h文件暴露出來
3.三、利用上面2.6的方案二生成發佈版本的靜態庫,記得修改支持的最低版本,修改 把.framework的庫由動態庫改成靜態庫
修改支持的最低版本
修改 把`.framework`的庫由 動態 改成 靜態庫
1 2 3 4 5 6 |
|
使用xcodebuild生成靜Release下模擬器的靜態庫
提示:你若是須要 Debug 下的靜態庫,參照 2.6 自行生成
3.四、測試一下是否能夠運行(提示:若是不把動態庫改成靜態庫會運行報錯,若是你想強行使用動態庫,那麼你就在:TARGETS->General->Embedded Binaries 添加你的庫)
測試OK
3.五、合併 .framework 靜態庫
合併靜態庫
1 |
|
切記:合成的是二進制文件而不是framework,最後合成的二進制文件替代以前的二進制文件便可
4、總結
4.一、靜態庫打包的完整正確步驟
<1>、肯定是靜態庫
.a 的確定是靜態庫
.framework的須要設置連接類型,project -> Build Settings-> 搜索 Mach-o Type ; 改成靜態庫選擇 Static Library
`.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
在複合項目中添加一個`.framework`的靜態庫`JKTools`
<2>、建立一個JKTest類,建立一個類方法,並把JKTest的.h放到建立靜態庫生成的.h文件裏面
建立一個`JKTest`類,建立一個類方法
把JKTest的`.h`放到建立靜態庫生成的`.h`文件裏面
<3>、選中JKTools,修改下面選項
修改JKTools支持的最低版本爲9.0,看本身項目了
設置爲靜態庫
修改 Build Settings ->Build Active ->NO,這樣編譯以後,debug真機下支持debug真機下全部的架構,debug模擬器下支持debug模擬器下全部的架構
把須要暴露的文件放到Public裏面
<4>、在符合項目添加咱們的靜態庫依賴
在符合項目添加咱們的靜態庫依賴
<5>、測試
導入#import,調用下面的方法
1 |
|
打印結果:
1 |
|
<6>、有關 .framework的文件導出,我就再也不重複了,也就是上面2.6的步驟,有關合上面也有講述
5、將MRC的項目,打包成靜態庫, 能夠在ARC下直接使用, 不須要轉換
5.一、應用場景
你找到一個功能是ARC項目下的,你想用,裏面有不少的類,你怎麼把他們搬到ARC項目下使用???
5.二、解決方案一(適用於類不太的狀況)
<1>、咱們模擬一個類JKTools,它是MRC下的項目
咱們模擬一個類JKTools,它是MRC下的項目
<2>、咱們把JKTools的.h與.m拖到ARC的工程下,報錯是確定的,咱們看下如何處理。以下圖
在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拖進去,把並修改項目爲 MRC
修改項目爲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
建立一個`Swift` 下的 `.framework` 工程,命名爲 `JKTools` ,同時建立一個類`JKTest`,寫一個方法 `jk_test`
5.二、把支持的最低版本調爲 9.0,具體的看本身項目
把支持的最低版本調爲 9.0,具體的看本身項目
5.三、修改 Build Settings ->Build Active ->NO,這樣編譯以後,debug真機下支持debug真機下全部的架構,debug模擬器下支持debug模擬器下全部的架構
5.四、修改 爲靜態庫
修改 爲靜態庫
5.五、在release下編譯模擬器與真機,生成像一個的.framework 文件,把類裏面的二進制文件合併成一個,步驟和上面同樣,再也不重複了
5.六、測試靜態庫的使用,結果顯示是OK的
測試靜態庫的使用,結果顯示是OK的
到此,靜態庫的相關知識記錄到這,相比較其餘的博客仍是比較詳細的。