一、靜態庫簡介
1.1、庫:是程序代碼的集合,是共享程序代碼的一種方式。
-
1.2、根據源代碼的公開情況,庫可以分爲2種類型
-
<1>、開源庫
公開源代碼,能看到具體實現,比如我們常見的:AFNetworking、SDWebImage、MJRefresh 等等 -
<2>、閉源庫
不公開源代碼,是經過編譯後的二進制文件,看不到具體實現
主要分爲:靜態庫、動態庫
-
<1>、開源庫
-
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靜態庫
時一定注意版本 - (1)、合併
-
- 合併步驟:
三、.framework
靜態庫的製作
-
3.1、創建項目時, 直接選擇
.framework
靜態庫
-
3.2、創建一個繼承於
NSObject
的JKTest
類,並寫一個類方法,把該類的.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 就好
- <1>、確定是靜態庫
-
4.2、
.a靜態庫
和.framework靜態庫
的區別?- <1>、
.a
是一個純二進制文件,.framework
中除了有二進制文件之外還有資源文件,.bundle
就是資源文件 - <2>、
.a
文件不能直接使用, 至少要有.h文件的配合;.framework
文件可以直接使用 - <3>、
.a
+.h
+sourceFile
=.framework
- <4>、建議使用
.framework
- <1>、
-
4.3、靜態庫開發中的常見問題
- 問題1: 有些第三方庫會使用到一些圖片素材,例如公司的logo,xib文件等,如何做?
答:創建一個.bundle
文件,創建方式看 資源文件 .buldle 的添加第十。 - 問題2: 如果用戶需要導入的頭文件過多怎麼加?
答:在創建.framework
項目會默認生成一個.h
文件,我們可以把其他的.h
文件導入 默認生成一個.h
文件 中 - 問題3: 靜態庫程序怎樣測試?
答:創建一個創建複合項目,看下面4.4
創建的步驟
- 問題1: 有些第三方庫會使用到一些圖片素材,例如公司的logo,xib文件等,如何做?
-
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.h
和JKTools.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的
- <1>、創建一個
到此,靜態庫的相關知識記錄到這,相比較其他的博客還是比較詳細的。遇到任何問題都可以再我的個人信息裏面來聯繫我