一、靜態(tài)庫簡介
1.1、庫:是程序代碼的集合,是共享程序代碼的一種方式。
-
1.2、根據源代碼的公開情況,庫可以分為2種類型
-
<1>、開源庫
公開源代碼,能看到具體實現,比如我們常見的:AFNetworking、SDWebImage、MJRefresh 等等 -
<2>、閉源庫
不公開源代碼,是經過編譯后的二進制文件,看不到具體實現
主要分為:靜態(tài)庫、動態(tài)庫
-
<1>、開源庫
-
1.3、靜態(tài)庫和動態(tài)庫的存在形式
- 靜態(tài)庫:
.a和.framework - 動態(tài)庫:
.dylib和.framework
- 靜態(tài)庫:
-
1.4、靜態(tài)庫和動態(tài)庫在使用上的區(qū)別
-
靜態(tài)庫:鏈接時,靜態(tài)庫會被完整地復制到可執(zhí)行文件中,被多次使用就有多份冗余拷貝(如下圖所示)
靜態(tài)庫 -
動態(tài)庫:鏈接時不復制,程序運行時由系統動態(tài)加載到內存,供程序調用,系統只加載一次,多個程序共用,節(jié)省內存(如下圖所示)
動態(tài)庫需要注意的是:iOS平臺 在 iOS8 之前,蘋果不允許第三方框架使用動態(tài)方式加載,從 iOS8 開始允許開發(fā)者有條件地創(chuàng)建和使用動態(tài)框架,這種框架叫做 Cocoa Touch Framework。雖然同樣是動態(tài)框架,但是和系統 framework 不同,app 中使用 Cocoa Touch Framework 制作的動態(tài)庫 在打包和提交 app 時會被放到 app main bundle 的根目錄 中,運行在沙盒里,而不是系統中。也就是說,不同的 app 就算使用了同樣的 framework,但還是會有多份的框架被分別簽名,打包和加載。不過 iOS8 上開放了 App Extension 功能,可以為一個應用創(chuàng)建插件,這樣主app和插件之間共享動態(tài)庫還是可行的。
蘋果系統專屬的framework 是共享的(如UIKit), 但是我們自己使用 Cocoa Touch Framework 制作的動態(tài)庫是放到 app bundle 中,運行在沙盒中的
-
靜態(tài)庫:鏈接時,靜態(tài)庫會被完整地復制到可執(zhí)行文件中,被多次使用就有多份冗余拷貝(如下圖所示)
-
1.5、 靜態(tài)庫應用場景?
-
保護自己的核心代碼,比如國內的環(huán)信,百度地圖,高德地圖,友盟,個推,他們掌握有核心技術,同時是又希望更多的程序員來使用其技術,因此采用"閉源"的方式開發(fā)使用,你只能看到他們的
.h文件以及一些不重要的.m文件 - 將
MRC的項目,打包成靜態(tài)庫, 可以在ARC下直接使用, 不需要轉換
-
保護自己的核心代碼,比如國內的環(huán)信,百度地圖,高德地圖,友盟,個推,他們掌握有核心技術,同時是又希望更多的程序員來使用其技術,因此采用"閉源"的方式開發(fā)使用,你只能看到他們的
-
1.6、靜態(tài)庫的特點?
- 由
.a和.h組成 - 看不到具體實現的代碼
- 由
二、.a 靜態(tài)庫的制作
-
2.1、 創(chuàng)建項目時, 直接選擇靜態(tài)庫(
.a)
創(chuàng)建項目時, 直接選擇靜態(tài)庫(`.a`) -
2.2、定義一個類方法
+(void)jk_test,在.h里面暴露出來jk_test
定義一個類方法`+(void)jk_test` -
2.3、添加暴露的文件
添加暴露的文件 -
2.4、分別在真機與6s下編譯,查看生成的.a與暴露文件
分別在真機與6s下編譯,查看生成的.a與暴露文件
分別在真機與6s下編譯,查看生成的.a與暴露文件 -
2.5、新建一個工程測試 上面我們創(chuàng)建的
.a文件 與 暴露文件 是否可以使用
新建一個工程測試 上面我們創(chuàng)建的 `.a` 文件 與 暴露文件 是否可以使用-
測試結果:
- 1、使用6S模擬器進行測試, 可以使用
- 2、使用低型號模擬器測試,; 失敗
- 3、使用真機, 編譯; 失敗
分析原因:原因是靜態(tài)庫分架構,不同的CPU架構是不一樣的 ,如果
.a靜態(tài)庫不支持架構,運行會報錯- 靜態(tài)庫所支持的架構
- 模擬器:
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靜態(tài)庫所支持的架構:cd 進入 .a靜態(tài)庫所在的文件夾 lipo -info 庫文件名我們以上面在模擬器下的
.a靜態(tài)庫為例,如下圖
我們以上面在模擬器下的 `.a靜態(tài)庫` 為例
-
-
2.6、怎樣一次編譯支持多個架構的的靜態(tài)庫?
-
解決方案
一:在Build Settings->Build Active->NO,這樣設置之后,debug真機下支持debug真機下所有的架構,debug模擬器下支持debug模擬器下所有的架構,再重復上面的測試,在iPhone5或者iPhone4下就不會報錯了
在 `Build Settings` ->` Build Active` ->` NO`注意:你的xcode要有上面架構的機型,否則只會包含有的架構,如果沒有
i386架構,你可以 下載 4s~5 模擬器,再重復上面的操作 -
解決方案
二:xcodebuild 命令行生成靜態(tài)庫參考博客-
debug(調試)版本
xcodebuild -target 要生成的靜態(tài)庫目名 -configuration Debug -sdk iphoneos -arch armv7 -arch arm64 xcodebuild -target 要生成的靜態(tài)庫目名 -configuration Debug -sdk iphonesimulator -arch i386 -arch x86_64 -
release(發(fā)布)版本
xcodebuild -target 要生成的靜態(tài)庫目名 -configuration Release -sdk iphoneos -arch armv7 -arch arm64 xcodebuild -target 要生成的靜態(tài)庫目名 -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64 -
提示:我們只需要生成發(fā)布版本的就好,如下步驟
# 1、cd 進入靜態(tài)庫項目 cd 靜態(tài)庫項目 # 2、操作上面 release(發(fā)布)版本 的命令注意:在使用過 xcodebuild ,再利用
lipo -info 靜態(tài)庫名檢測,響應的架構都支持
-
-
-
2.7、通過上面我們可以知道
.a靜態(tài)庫在debug模式下的真機和模擬器編譯各會生成一個.a靜態(tài)庫,在release模式下的真機和模擬器編譯也各會生成一個.a靜態(tài)庫,那么我們給別人哪些 .a靜態(tài)庫用呢?
答案是:給其他人在release模式下的:真機與模擬器下的.a靜態(tài)庫提示:
.a靜態(tài)庫在 測試版本 與 發(fā)布版本 的特點- Debug(調試版本):1、調試版本會包含完整的符號信息,以方便調試;2、調試版本不會對代碼進行優(yōu)化
- Release(發(fā)布版本): 1、發(fā)布版本不會包含完整的符號信息;2、發(fā)布版本的執(zhí)行代碼是進行過優(yōu)化的;3、發(fā)布版本的大小會比調試版本的略小;4、在執(zhí)行速度方面,發(fā)布版本會更快些,但不意味著會有顯著的提升
-
2.8、我們給用戶發(fā)布版本的兩個.a靜態(tài)庫(真機下的release模式下的.a靜態(tài)庫與模擬器release模式下的.a靜態(tài)庫),如果想要一個靜態(tài)庫, 既可以在模擬器上運行, 也可以在真機上運行怎么做?
答案:把發(fā)布版本的兩個.a靜態(tài)庫合成一個.a靜態(tài)庫??- 合并步驟:
-
<1>、檢查發(fā)布版本的兩個靜態(tài)庫是否支持的 架構都全
檢查發(fā)布版本的兩個靜態(tài)庫是否支持的 架構都全 -
<2>、合并
.a
合并 `.a`cd 進入 Products 文件夾 lipo -create Release-iphoneos/libJKOCProjectTool.a Release-iphonesimulator/libJKOCProjectTool.a -output NewJKOCProjectTool.a提示:
NewJKOCProjectTool.a是生成的新的.a,合成的.a的大小是合成前兩個.a大小的和 -
<3>、合成后的
.a靜態(tài)庫的特點- (1)、合并
.a的好處,開發(fā)過程中既可以在真機上調試,也可以在模擬器上調試 - (2)、 合并
.a的壞處,如果靜態(tài)庫太大,合并打包后,會非常大,因此很多第三方的靜態(tài)庫的.a是區(qū)分版本的
提示:今后在使用
.a靜態(tài)庫時一定注意版本 - (1)、合并
-
- 合并步驟:
三、.framework 靜態(tài)庫的制作
-
3.1、創(chuàng)建項目時, 直接選擇
.framework靜態(tài)庫
創(chuàng)建項目時, 直接選擇.framework靜態(tài)庫 -
3.2、創(chuàng)建一個繼承于
NSObject的JKTest類,并寫一個類方法,把該類的.h文件暴露出來
創(chuàng)建一個繼承于`NSObject`的`JKTest`類,并寫一個類方法提示:記得把需要暴露的
.h文件導入到在創(chuàng)建靜態(tài)庫的時候生成的.h文件里面,如上面的JKOCProjectTool.h把該類的.h文件暴露出來 -
3.3、利用上面
2.6的方案二生成發(fā)布版本的靜態(tài)庫,記得修改支持的最低版本,修改 把.framework的庫由動態(tài)庫改為靜態(tài)庫
修改支持的最低版本
修改 把`.framework`的庫由 動態(tài) 改為 靜態(tài)庫// 1.cd 進入靜態(tài)庫項目 cd JKOCProjectTool // 2.使用xcodebuild生成靜Release下真機的靜態(tài)庫 xcodebuild -target JKOCProjectTool -configuration Release -sdk iphoneos -arch armv7 -arch arm64 // 3.使用xcodebuild生成靜Release下模擬器的靜態(tài)庫 xcodebuild -target JKOCProjectTool -configuration Release -sdk iphonesimulator -arch i386 -arch x86_64使用xcodebuild生成靜Release下模擬器的靜態(tài)庫提示:你如果需要
Debug下的靜態(tài)庫,參照2.6自行生成 -
3.4、測試一下是否可以運行(提示:如果不把動態(tài)庫改為靜態(tài)庫會運行報錯,如果你想強行使用動態(tài)庫,那么你就在:
TARGETS->General->Embedded Binaries添加你的庫)
測試OK -
3.5、合并
.framework靜態(tài)庫
合并靜態(tài)庫lipo -create 真機的JKOCProjectTools路徑 模擬器的JKOCProjectTools路徑 -output 合并后的JKOCProjectTools文件切記:合成的是二進制文件而不是framework,最后合成的二進制文件替代之前的二進制文件即可
-
3.6、補充:靜態(tài)庫操作
-
<1>、合成不同架構的庫(也就是上面的
3.5)lipo -create xx xx -output xxx -
<2>、分解合成庫
lipo -thin 架構名稱 xx -output xx -
<3>、測試靜態(tài)庫 所支持的架構
cd 進入 靜態(tài)庫所在的文件夾 lipo -info 庫文件名 -
<4>、從合成庫移除某個架構
lipo -remove 架構名稱 xx -output xx
提示:上面3.6中的
xx代表靜態(tài)庫名 -
四、總結
-
4.1、靜態(tài)庫打包的完整正確步驟
- <1>、確定是靜態(tài)庫
-
.a的肯定是靜態(tài)庫 -
.framework的需要設置鏈接類型,project->Build Settings-> 搜索Mach-o Type; 改為靜態(tài)庫選擇Static Library
`.framework`的需要設置鏈接類型
-
- <2>、確定支持模擬器或者真機中的所有架構
- 如果使用的2.6類里面的 方案一 那就是xcode要支持所有的架構的模擬器,并且修改 Build Settings ->Build Active ->NO,這樣編譯之后,debug真機下支持debug真機下所有的架構,debug模擬器下支持debug模擬器下所有的架構
- 如果使用的2.6類里面的 方案二
xcodebuild方法就可以支持所有的架構
- <3>、提供的靜態(tài)庫應該是
release版本- 如果使用的2.6類里面的 方案一:項目 -> Edit Scheme -> Run -> Release/Debug 分別進行編譯
- 如果使用的2.6類里面的 方案二
xcodebuild方法,在命令類里面輸入 Release 就好
- <1>、確定是靜態(tài)庫
-
4.2、
.a靜態(tài)庫和.framework靜態(tài)庫的區(qū)別?- <1>、
.a是一個純二進制文件,.framework中除了有二進制文件之外還有資源文件,.bundle就是資源文件 - <2>、
.a文件不能直接使用, 至少要有.h文件的配合;.framework文件可以直接使用 - <3>、
.a+.h+sourceFile=.framework - <4>、建議使用
.framework
- <1>、
-
4.3、靜態(tài)庫開發(fā)中的常見問題
- 問題1: 有些第三方庫會使用到一些圖片素材,例如公司的logo,xib文件等,如何做?
答:創(chuàng)建一個.bundle文件,創(chuàng)建方式看 資源文件 .buldle 的添加第十。 - 問題2: 如果用戶需要導入的頭文件過多怎么加?
答:在創(chuàng)建.framework項目會默認生成一個.h文件,我們可以把其他的.h文件導入 默認生成一個.h文件 中 - 問題3: 靜態(tài)庫程序怎樣測試?
答:創(chuàng)建一個創(chuàng)建復合項目,看下面4.4創(chuàng)建的步驟
- 問題1: 有些第三方庫會使用到一些圖片素材,例如公司的logo,xib文件等,如何做?
-
4.4、創(chuàng)建一個創(chuàng)建復合項目(符合工程的名字定義為:
復合項目)-
<1>、在復合項目中添加一個
.framework的靜態(tài)庫JKTools
在復合項目中添加一個`.framework`的靜態(tài)庫`JKTools` -
<2>、創(chuàng)建一個
JKTest類,創(chuàng)建一個類方法,并把JKTest的.h放到創(chuàng)建靜態(tài)庫生成的.h文件里面
創(chuàng)建一個`JKTest`類,創(chuàng)建一個類方法
把JKTest的`.h`放到創(chuàng)建靜態(tài)庫生成的`.h`文件里面 -
<3>、選中
JKTools,修改下面選項
修改JKTools支持的最低版本為9.0,看自己項目了
設置為靜態(tài)庫
修改 Build Settings ->Build Active ->NO,這樣編譯之后,debug真機下支持debug真機下所有的架構,debug模擬器下支持debug模擬器下所有的架構
把需要暴露的文件放到Public里面 -
<4>、在復合項目添加我們的靜態(tài)庫依賴
在符合項目添加我們的靜態(tài)庫依賴 -
<5>、測試
導入#import <JKTools/JKTools.h>,調用下面的方法[JKTest jk_test];打印結果:
復合項目的測試 <6>、有關
.framework的文件導出,我就不再重復了,也就是上面2.6的步驟,有關合上面也有講述
-
五、將MRC的項目,打包成靜態(tài)庫, 可以在ARC下直接使用, 不需要轉換
5.1、應用場景
你找到一個功能是ARC項目下的,你想用,里面有很多的類,你怎么把他們搬到ARC項目下使用???-
5.2、解決方案一(適用于類不太的情況)
-
<1>、我們模擬一個類JKTools,它是MRC下的項目
我們模擬一個類JKTools,它是MRC下的項目 -
<2>、我們把JKTools的.h與.m拖到ARC的工程下,報錯是肯定的,我們看下如何處理。如下圖
在ARC圖中路徑找到MRC下的.m文件,雙擊輸入-fno-objc-arc
提示:在ARC圖中路徑找到
MRC下的.m文件,雙擊輸入-fno-objc-arc,再運行就不會報錯了 -
-
5.3、解決方案二(適用于MRC的類很多的情況):把MRC下的類打包成靜態(tài)庫,
.a或者.framework都可以,下面以打包成.framework為例,步驟如下- <1>、創(chuàng)建一個
.framework項目,這里名字一JKTools為例,把上面JKTools.h和JKTools.m拖進去,把并修改項目為MRC
修改項目為MRC
在TARGETS->Build Settings下搜Automatic Reference,改為 NO;其中YES為ARC,NO為MRC。 - <2>、重復
4.4里面<3>的步驟 - <3>、生成發(fā)布版本的靜態(tài)庫以及合并真機與模擬器的二進制文件,最后把合并的二進制文件替換掉 真機下
framework里面的二進制文件 - <4>、把framework拖入 ARC的項目,直接導入framework里面的.h文件查看是否可以,經過測試時OK的,不懂的你可以聯系我
五、Swift打包動態(tài)庫
-
5.1、創(chuàng)建一個
Swift下的.framework工程,命名為JKTools,同時創(chuàng)建一個類JKTest,寫一個方法jk_test
創(chuàng)建一個`Swift` 下的 `.framework` 工程,命名為 `JKTools` ,同時創(chuàng)建一個類`JKTest`,寫一個方法 `jk_test` -
5.2、把支持的最低版本調為 9.0,具體的看自己項目
把支持的最低版本調為 9.0,具體的看自己項目 5.3、修改 Build Settings ->Build Active ->NO,這樣編譯之后,debug真機下支持debug真機下所有的架構,debug模擬器下支持debug模擬器下所有的架構
-
5.4、修改 為靜態(tài)庫
修改 為靜態(tài)庫 5.5、在release下編譯模擬器與真機,生成像一個的.framework 文件,把類里面的二進制文件合并成一個,步驟和上面一樣,不再重復了
-
5.6、測試靜態(tài)庫的使用,結果顯示是OK的
測試靜態(tài)庫的使用,結果顯示是OK的
- <1>、創(chuàng)建一個
到此,靜態(tài)庫的相關知識記錄到這,相比較其他的博客還是比較詳細的。遇到任何問題都可以再我的個人信息里面來聯系我


































