什么是庫朴读?
庫是共享程序代碼的方式辖所,一般分為動(dòng)態(tài)庫和靜態(tài)庫。
- 靜態(tài)庫:.a和.framework
- 動(dòng)態(tài)庫:.dylib和.framework
在實(shí)際的項(xiàng)目開發(fā)中磨德,經(jīng)常會(huì)使用到庫缘回,庫分為靜態(tài)庫和動(dòng)態(tài)庫兩種。和多數(shù)人所熟悉的動(dòng)態(tài)語言和靜態(tài)語言一樣典挑,這里的所謂靜態(tài)和動(dòng)態(tài)是相對(duì)編譯期和運(yùn)行期的:靜態(tài)庫在程序編譯時(shí)會(huì)被鏈接到目標(biāo)代碼中酥宴,程序運(yùn)行時(shí)將不再需要改靜態(tài)庫;而動(dòng)態(tài)庫在程序編譯時(shí)并不會(huì)被鏈接到目標(biāo)代碼中您觉,只是在程序運(yùn)行時(shí)才被載入拙寡,因?yàn)樵诔绦蜻\(yùn)行期間還需要?jiǎng)討B(tài)庫的存在。
靜態(tài)庫和動(dòng)態(tài)庫區(qū)別
- 靜態(tài)庫:鏈接時(shí)琳水,靜態(tài)庫會(huì)被完整的復(fù)制到可執(zhí)行文件中肆糕,被多次使用就又多份冗余拷貝
- 動(dòng)態(tài)庫:鏈接時(shí)不復(fù)制,程序運(yùn)行時(shí)由系統(tǒng)動(dòng)態(tài)加載到內(nèi)存在孝,供程序調(diào)用诚啃,系統(tǒng)只會(huì)加載一次,多個(gè)程序共用私沮,節(jié)省內(nèi)存
注意:項(xiàng)目中如果使用了自制的動(dòng)態(tài)庫(framework)不能被上傳到AppStore
.a和.framewrok有什么區(qū)別始赎?
- .a是一個(gè)純二進(jìn)制文件,.framework是一個(gè)文件夾,文件夾中除了有二進(jìn)制文件之外還有資源文件造垛。* .a文件不能直接使用魔招,至少要有.h文件配合,.framework文件可以直接使用五辽。* .a + .h + sourceFile = .framework办斑。
靜態(tài)庫的應(yīng)用場(chǎng)景
- 希望更多的開發(fā)者在程序中集成,但是又不想公布自己的核心技術(shù)杆逗;對(duì)外暴露統(tǒng)一接口乡翅,開發(fā)者調(diào)用靜態(tài)庫即可。
- 項(xiàng)目開發(fā)中有一部分核心代碼髓迎,非核心開發(fā)人員倘若離職,對(duì)于公司來說是一種損失
1. a靜調(diào)庫的編譯
1.靜態(tài)庫的創(chuàng)建:左側(cè)為.framework 右側(cè)為.a
2.創(chuàng)建工具類建丧,并暴露接口新建工具類排龄,并在buildPhrase中添加需要暴露的.h文件
3.分別在不同的環(huán)境下編譯,從而得到支持不同環(huán)境的靜調(diào)庫
4.查看不同環(huán)境下的靜態(tài)庫
在不同的文件夾下可以查看不同環(huán)境使用的.a靜調(diào)庫文件翎朱,新建項(xiàng)目橄维,將.a文件拖拽到項(xiàng)目中估計(jì)可使用
靜態(tài)庫中的架構(gòu)問題
當(dāng)使用真機(jī)環(huán)境的.a文件在模擬中編譯或者運(yùn)行時(shí),會(huì)報(bào)架構(gòu)的錯(cuò)誤 拴曲。
設(shè)備的CPU架構(gòu)
不同的設(shè)備使用的CPU不同
CPU的不同就造成使用的CPU架構(gòu)(即指令集)不同
-
靜態(tài)庫有其支持的CPU架構(gòu)
- 如果靜態(tài)庫在其不支持的CPU架構(gòu)上面運(yùn)行就會(huì)報(bào)錯(cuò)
模擬器使用的CPU架構(gòu)
iPhone4s-iPhone5:i386
iPhone5s-iPhone6Plus:x86_64
真機(jī)使用的CPU架構(gòu)
iPhone3gs-iPhone4sP:armv7
iPhone5-iPhone5c:armv7s
iPhone5s-iPhone6plus:arm64
注意: 支持armv7的靜態(tài)庫可以在armv7s上正常使用* 查看靜態(tài)庫的架構(gòu)(終端命令)
$ lipo -info 靜態(tài)庫地址
合并靜態(tài)庫
$ lipo create 靜態(tài)庫1 靜態(tài)庫2 output 合并后的靜態(tài)庫
如何使靜調(diào)庫支持多種CPU架構(gòu)
想要制作的靜態(tài)庫既支持i386架構(gòu)也支持x86_64架構(gòu)争舞,有兩種解決方法.
-
修改靜態(tài)庫的編譯環(huán)境并重新編譯
6.png
在termnal中使用命令將多個(gè)靜態(tài)庫合并
$ lipo -create Debug-iphoneos/libStaticLibrary.a Debug-iphonesimulator/libStaticLibrary.a -output libnewstatic.a
合并后的靜調(diào)庫的大小>=合并之前靜態(tài)庫大小之和
開發(fā)環(huán)境:需要支持真機(jī)以及模擬器的靜態(tài)庫
生產(chǎn)環(huán)境:只需要支持真機(jī)的靜態(tài)庫即可
2 .framework靜態(tài)庫的編譯
第一步與.a文件文件創(chuàng)建一樣,選擇framework澈灼,點(diǎn)開以后發(fā)現(xiàn)竞川,項(xiàng)目中已經(jīng)存在一個(gè)與項(xiàng)目名稱一樣的主頭文件(這是蘋果推薦的方式 )
1.將需要暴露的頭文件添加到public(拖入即可)
注意:將需要暴露的頭文件放到主頭文件中
2.步驟跟.a文件一致,分別在真機(jī)以及模擬器環(huán)境編譯叁熔,得到兩個(gè)不同環(huán)境的.framework
3.使用.framework并運(yùn)行
查看控制臺(tái)發(fā)現(xiàn)報(bào)錯(cuò)委乌,發(fā)現(xiàn)制作的framework為動(dòng)態(tài)庫,動(dòng)態(tài)庫的使用荣回,需要在target中手動(dòng)添加動(dòng)態(tài)庫遭贸。(只能作為測(cè)試使用,蘋果禁止自制的動(dòng)態(tài)庫上架心软,上架前切記修改為靜態(tài)庫)
4.修改編譯環(huán)境壕吹,編譯靜態(tài)庫buildsetting 搜索mach 并修改
使用該方法制作的靜態(tài)庫,可以運(yùn)行删铃,但是在4s中是無法運(yùn)行的耳贬,會(huì)報(bào)CPU架構(gòu)的錯(cuò)誤,通過$lipo -info StaticFramework
查看framework所支持的架構(gòu)猎唁,目前這樣制作的framework只支持x86架構(gòu)效拭,因此4s不能運(yùn)行** 注意 :**cd 到.framework的路徑是不夠的,因?yàn)閮H僅是一個(gè)文件夾,真正的靜態(tài)庫是一個(gè)二進(jìn)制文件.因此查看架構(gòu)信息的時(shí)候需要跟這個(gè)靜態(tài)庫名字修改架構(gòu)缎患,使制作的framework支持所有架構(gòu)
靜調(diào)庫的合并與.a文件一樣慕的,在此就不做贅述。至此SDK的開發(fā)就到此為止挤渔,真正的SDK開發(fā)需要在項(xiàng)目中一邊開發(fā)一邊調(diào)試
3 SDK靜調(diào)庫的調(diào)試
單獨(dú)進(jìn)行核心代碼SDK的開發(fā)肮街,開發(fā)完成以后需要拖到項(xiàng)目中調(diào)試,這樣是本末倒置的判导。SDK的開發(fā)需要在項(xiàng)目中調(diào)試以及開發(fā)嫉父。
創(chuàng)建完成以后,項(xiàng)目中的結(jié)構(gòu)發(fā)生變化眼刃,變化的位置已經(jīng)已經(jīng)圈出
在framework文件目錄下創(chuàng)建核心代碼類绕辖,并在項(xiàng)目中需要的地方import主頭文件,靜調(diào)庫的制作就不贅述了擂红,與上面的一致仪际。
4 制作靜態(tài)庫時(shí)注意的幾點(diǎn):
- 圖片資源的處理:兩種靜態(tài)庫,一般都是把圖片文件單獨(dú)的放在一個(gè).bundle文件中昵骤,一般.bundle的名字和.a或.framework的名字相同树碱。.bundle文件很好弄,新建一個(gè)文件夾变秦,把它改名為.bundle就可以了成榜,右鍵,顯示包內(nèi)容可以向其中添加圖片資源蹦玫。
- category是我們實(shí)際開發(fā)項(xiàng)目中經(jīng)常用到的赎婚,把category打成靜態(tài)庫是沒有問題的,但是在用這個(gè)靜態(tài)庫的工程中樱溉,調(diào)用category中的方法時(shí)會(huì)有找不到該方法的運(yùn)行時(shí)錯(cuò)誤(selector not recognized)惑淳,解決辦法是:在使用靜態(tài)庫的工程中配置other linker flags的值為-ObjC -all_load