靜態(tài)庫(kù):以
.a
和.framework
為文件后綴名葵蒂。
動(dòng)態(tài)庫(kù):以.tbd
(之前叫.dylib
) 和.framework
為文件后綴名交播。
靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別
靜態(tài)庫(kù):鏈接時(shí)會(huì)被完整的復(fù)制到可執(zhí)行文件中,被多次使用
(指多個(gè)應(yīng)用程序使用)
就有多份拷貝到系統(tǒng)中刹勃。
動(dòng)態(tài)庫(kù):鏈接時(shí)不復(fù)制堪侯,程序運(yùn)行時(shí)由系統(tǒng)動(dòng)態(tài)加載到內(nèi)存,系統(tǒng)只加載一次荔仁,多個(gè)程序共用(如系統(tǒng)的UIKit.framework
等),節(jié)省內(nèi)存乏梁。
系統(tǒng)對(duì)動(dòng)態(tài)庫(kù)的支持
iOS8.0以前是不支持使用自定義動(dòng)態(tài)庫(kù),iOS8.0以后,可以使用.
由于提交代碼審核的時(shí)候需要提交動(dòng)態(tài)庫(kù)的簽名,所以動(dòng)態(tài)從自己服務(wù)器下載動(dòng)態(tài)庫(kù)實(shí)現(xiàn)iOS熱更新是不能實(shí)現(xiàn)的
我們先來(lái)看一下iOS設(shè)備有哪些架構(gòu)次洼,因?yàn)橄旅嬉玫剑?/h5>
模擬器:
iPhone4s-iPnone5:i386
iPhone5s-iPhone7 Plus:x86_64
真機(jī):
iPhone3gs-iPhone4s:armv7
iPhone5-iPhone5c:armv7s
iPhone5s-iPhone6s:Plus:arm64
支持armv7的靜態(tài)庫(kù)可以在armv7s上正常運(yùn)行。
.a靜態(tài)庫(kù)的制作(1.選擇頭文件 2.選擇所有架構(gòu))
模擬器:
iPhone4s-iPnone5:i386
iPhone5s-iPhone7 Plus:x86_64
真機(jī):
iPhone3gs-iPhone4s:armv7
iPhone5-iPhone5c:armv7s
iPhone5s-iPhone6s:Plus:arm64
支持armv7的靜態(tài)庫(kù)可以在armv7s上正常運(yùn)行。
1遇骑、先創(chuàng)建一個(gè)新的Xcode工程Test卖毁,需要選擇下面這個(gè)模板:
創(chuàng)建完成后是這個(gè)樣子的:
2、我們把默認(rèn)生成的Test.h和Test.m刪掉落萎,重新創(chuàng)建一個(gè)類PrintString亥啦,在這個(gè)類里面添加一個(gè)單純打印字符串的簡(jiǎn)單方法:
3、選擇添加公開(kāi)頭文件
為了讓使用者知道有哪些方法可以用练链,我們需要公開(kāi)頭文件翔脱,這里我們公開(kāi)PrintString.h:
4、修改配置
我們需要把Build Active Architecture Only修改為NO媒鼓,否則生成的靜態(tài)庫(kù)就只支持當(dāng)前選擇設(shè)備的架構(gòu)届吁。
5错妖、然后編譯
我們分別選擇Generic iOS Device
和任意一個(gè)模擬器
各編譯一次,編譯完后疚沐,我們會(huì)看到工程中Products
文件夾下的libTest.a
由紅色變成了黑色暂氯,然后show in finder,看看生成的文件:
我們看到它為真機(jī)和模擬器都生成了.a靜態(tài)庫(kù)亮蛔。里面都包含我們選擇公開(kāi)的頭文件痴施。
我們來(lái)看看靜態(tài)庫(kù)支持的框架:命令為lipo -info 靜態(tài)庫(kù)名字
我們看到,Debug-iphoneos里面的靜態(tài)庫(kù)支持的架構(gòu)有armv7
和arm64
所以它只能用于真機(jī)尔邓,在模擬器上會(huì)報(bào)錯(cuò)晾剖。Debug-iphonesimulator里面的靜態(tài)庫(kù)支持的架構(gòu)有i386
和x86_64
,所以它只能用于模擬器梯嗽,在真機(jī)上會(huì)報(bào)錯(cuò)。
如果想要讓模擬器和真機(jī)通用一個(gè)靜態(tài)庫(kù)沽损,我們可以使用終端命令來(lái)實(shí)現(xiàn)灯节。命令格式:lipo -create 第一個(gè).a文件的絕對(duì)路徑 第二個(gè).a文件的絕對(duì)路徑 -output 最終的.a文件路徑
我們看到生成了一個(gè)新的libTest.a文件。這個(gè)靜態(tài)庫(kù)就支持所有模擬器和所有真機(jī)了绵估。然后我們創(chuàng)建一個(gè)文件夾炎疆,把.a和頭文件都放進(jìn)去,我們最終需要使用的就是這個(gè)文件夾:
注意:為了開(kāi)發(fā)方便国裳,我們可以使用生成的通用靜態(tài)庫(kù)形入,但是最終上線的使用我們可以只導(dǎo)入真機(jī)的,這樣工程的體積也會(huì)小一些缝左。
使用生成的.a靜態(tài)庫(kù)
新建一個(gè)工程亿遂,將上面的通用靜態(tài)庫(kù)拖進(jìn)去,導(dǎo)入頭文件渺杉,就可以使用里面的方法了蛇数。經(jīng)過(guò)試驗(yàn),我們生成的靜態(tài)庫(kù)在真機(jī)上和模擬器上都能成功打印字符串:
.frameworke靜態(tài)庫(kù)的制作(1.選取頭文件 2.選取所有架構(gòu) 3.選擇靜態(tài)庫(kù))
1是越、先創(chuàng)建一個(gè)新的Xcode工程LibTest耳舅,需要選擇下面這個(gè)模板:
創(chuàng)建完成后是這個(gè)樣子的:
創(chuàng)建完成后我們可以看到,工程本身自帶一個(gè)LibTest.h
文件和一個(gè)Info.plist
文件倚评。
2浦徊、我們創(chuàng)建一個(gè)類PrintString
,添加一個(gè)單純打印字符串的簡(jiǎn)單方法:
3天梧、選擇添加公開(kāi)頭文件
為了讓使用者知道有哪些方法可以用盔性,我們需要公開(kāi)頭文件,我們需要在 并且將Target
->Build Phases
->Headers
中的Project中要暴露的頭文件拖拽到Pulic里面腿倚,這里我們公開(kāi)PrintString.h:
注意:暴露出來(lái)的頭文件中import的其他類也得添加到public中暴露出來(lái)纯出。如果不想將import的類暴露出來(lái)蚯妇,那么在頭文件中用@class 然后在對(duì)應(yīng)的.m文件中再import。
4暂筝、設(shè)置支持所有架構(gòu)(和.a制作一樣)
5箩言、修改生成的Mach-O格式,因?yàn)閯?dòng)態(tài)庫(kù)也可以是以framework形式存在焕襟,所以需要設(shè)置陨收,否則默認(rèn)打出來(lái)的是動(dòng)態(tài)庫(kù)。將target->BuildSetting->Mach-o Type 設(shè)為Static Library(默認(rèn)為Dynamic Library)
6鸵赖、編譯
我們分別選擇Generic iOS Device
和任意一個(gè)模擬器
各編譯一次务漩,編譯完后,我們會(huì)看到工程中Products文件夾下的LibTest.framework由紅色變成了黑色它褪,然后show in finder饵骨,看看生成的文件:
我們看到它為真機(jī)和模擬器都生成了LibTest.framework靜態(tài)庫(kù)。
我們來(lái)查看靜態(tài)庫(kù)支持的框架:與上面不同茫打,命令為lipo -info framework下的二進(jìn)制文件名字
如果想要讓模擬器和真機(jī)通用一個(gè)靜態(tài)庫(kù)居触,我們可以使用終端命令來(lái)實(shí)現(xiàn)。合并的命令與上面不同的是:framework靜態(tài)庫(kù)合并的不是framework,而是framework下的二進(jìn)制文件老赤,命令為:lipo -create 第一個(gè)framework下二進(jìn)制文件的絕對(duì)路徑 第二個(gè)framework下二進(jìn)制文件的絕對(duì)路徑 -output 最終的二進(jìn)制文件路徑
然后將任何一個(gè)framework中的二進(jìn)制文件替換成合并后的二進(jìn)制文件,然后把framework添加到要使用的項(xiàng)目中即可使用轮洋。
使用生成的.framework靜態(tài)庫(kù)
新建一個(gè)工程,將靜態(tài)庫(kù)拖進(jìn)去抬旺,導(dǎo)入頭文件弊予,就可以使用里面的方法了。經(jīng)過(guò)試驗(yàn)开财,我們生成的靜態(tài)庫(kù)在真機(jī)上和模擬器上都能成功打印字符串:
注意:
如果靜態(tài)庫(kù)中有category
類汉柒,則在使用靜態(tài)庫(kù)的項(xiàng)目配置中Other Linker Flags
需要添加參數(shù)-ObjC
或者-all_load
。
如果創(chuàng)建的framework
類中使用了.tbd
床未,則需要在實(shí)際項(xiàng)目中導(dǎo)入.tbd
動(dòng)態(tài)庫(kù)竭翠。
運(yùn)行調(diào)試靜態(tài)庫(kù)
如果你是開(kāi)發(fā)靜態(tài)庫(kù)的人,你會(huì)發(fā)現(xiàn)上面的方法只是制作靜態(tài)庫(kù)薇搁,并沒(méi)有辦法運(yùn)行看效果和調(diào)試bug斋扰,這時(shí)候我們可以這樣:
1、新建一個(gè)專門(mén)用來(lái)開(kāi)發(fā)靜態(tài)庫(kù)的正常工程Test:
2啃洋、添加一個(gè)靜態(tài)庫(kù)的target
我們看到它生成了幾樣?xùn)|西:
一個(gè)framework的target:在這里面修改靜態(tài)庫(kù)的配置們传货,例如支持的架構(gòu)、要暴露的頭文件們和Mach-O的配置宏娄。
一個(gè)LibTest文件夾:靜態(tài)庫(kù)里面的類們都放在這里面问裕。
product文件夾下面的LibTest.framework:在這里show in finder找到編譯后生成的靜態(tài)庫(kù)。
3孵坚、開(kāi)發(fā)調(diào)試代碼
我們看到程序可以正常運(yùn)行粮宛,并可以在動(dòng)態(tài)庫(kù)里面蹲點(diǎn)運(yùn)行窥淆。方便我們調(diào)試。
4巍杈、確保代碼沒(méi)問(wèn)題后忧饭,選擇對(duì)應(yīng)的target編譯生成。
5筷畦、后面的過(guò)程就與上面一樣了词裤。
補(bǔ)充:
上述生成的都是Debug版本的靜態(tài)庫(kù),生成Release版本的方法如下:
然后正常編譯兩次即可.