iOS靜態(tài)庫(kù)開(kāi)發(fā)由入門(mén)到成妖

【原創(chuàng)博文,轉(zhuǎn)載請(qǐng)注明出處!】
軟件開(kāi)發(fā)中庫(kù)的分類(lèi)無(wú)非就是開(kāi)源庫(kù)與閉源庫(kù)。在iOS領(lǐng)域,常見(jiàn)的開(kāi)源庫(kù)比如AFN、SDWebImage等。閉源庫(kù)如支付寶SDK、百度地圖等。今天本文所討論的靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)都屬于閉源庫(kù)。

靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的基本常識(shí):
1. 靜態(tài)庫(kù)的存在形式?

① .a
② .framework

2. 動(dòng)態(tài)庫(kù)的存在形式?

① .dylib
② .tbd
③ .framework

3. 靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別:

① 靜態(tài)庫(kù)在鏈接時(shí), 會(huì)被完整的復(fù)制到可執(zhí)行文件中; 被多次使用, 就有多份拷貝;
② 動(dòng)態(tài)庫(kù)則不會(huì)復(fù)制, 只有一份. 程序運(yùn)行時(shí)動(dòng)態(tài)加載到內(nèi)存; 系統(tǒng)只加載一次, 多個(gè)程序共用, 節(jié)省內(nèi)存;
③ 但是項(xiàng)目中如果使用到自己的動(dòng)態(tài)庫(kù), 不允許上架!!!
④ 后了在 WWDC2014上,蘋(píng)果公布了對(duì)iOS8開(kāi)放動(dòng)態(tài)加載dylib的接口,也就是說(shuō) 開(kāi)放了動(dòng)態(tài)庫(kù)掛載。

4. 靜態(tài)庫(kù)應(yīng)用場(chǎng)景:

① 保護(hù)核心代碼;
② 提高工程的編譯速度;
③ 將MRC的項(xiàng)目,打包成靜態(tài)庫(kù), 可以在ARC下直接使用, 不需要轉(zhuǎn)換。

5. 靜態(tài)庫(kù)的特點(diǎn):

① .a + .h文件
② 看不到具體實(shí)現(xiàn)的代碼

<1> Cocoa Touch Static Library中.a類(lèi)型的靜態(tài)庫(kù)

接下來(lái)我們?cè)赬code中新建一個(gè)靜態(tài)庫(kù)文件StaticLib。與一般新建App項(xiàng)目不一樣,這次我們打開(kāi)Xcode之后,在Framework & Library欄目下面選中Cocoa Touch Static Library。如下圖所示:


新建一個(gè).a的靜態(tài)庫(kù).png

接下來(lái)我們?cè)陟o態(tài)庫(kù)里面新建一個(gè)文件,如LogTool并提供一個(gè)方法+ (void)log;


為靜態(tài)庫(kù)添加一個(gè)測(cè)試類(lèi)LogTool和測(cè)試方法+ (void)log.png

這些操作之后,我們編譯一下(Command+B)就可以得到靜態(tài)庫(kù)文件libStaticLib.a。靜態(tài)庫(kù)文件的名字取決于我們新建靜態(tài)庫(kù)工程所取得名字,默認(rèn)為libXXX.a(XXX就是新建靜態(tài)庫(kù)項(xiàng)目的名稱(chēng))。

默認(rèn)生成的靜態(tài)庫(kù)文件

默認(rèn)生成的靜態(tài)庫(kù)不會(huì)包含頭文件。添加頭文件的方式有兩種,可以手動(dòng)將頭文件拖到.a文件所在的位置,但是對(duì)于靜態(tài)庫(kù)的頭文件較多,這樣會(huì)比較復(fù)雜。更簡(jiǎn)單的方式是通過(guò)Bulid Phases設(shè)置。選中Copy Files下面的“+”按鈕,即可將靜態(tài)庫(kù)所需的頭文件全部導(dǎo)入。Xcode默認(rèn)會(huì)將頭文件放到SubPath所指定的include文件夾中,可以刪掉這個(gè)path,頭文件就會(huì)自動(dòng)導(dǎo)入到.a所在的位置。操作看截圖所示:


給靜態(tài)庫(kù)添加頭文件.jpg

前面我們介紹過(guò)不同iOS設(shè)備芯片架構(gòu)不同,所以靜態(tài)庫(kù)文件需要支持不同的架構(gòu)。我們通過(guò)終端查看一下當(dāng)前的libStaticLib.a支持的架構(gòu)

Rephontil:~ zhouyong$ cd /Users/zhouyong/Desktop/Demo/StaticLibProject/TestStaticLib/StatilLib 
Rephontil:StatilLib zhouyong$ lipo -info libStaticLib.a
input file libStaticLib.a is not a fat file
Non-fat file: libStaticLib.a is architecture: x86_64

因?yàn)槭褂玫氖莍Phone7模擬器,屬于X86_64架構(gòu),所以默認(rèn)支持這個(gè)。如果需要支持早期的設(shè)備如iPhone5等,則通過(guò)Build Settings,找到Build Active Architecture Only并設(shè)置為No,這樣就可以支持出當(dāng)前選擇的模擬器型號(hào)之外的多種架構(gòu)了。

設(shè)置靜態(tài)庫(kù)支持所有架構(gòu)..png

上面獲得的靜態(tài)庫(kù)只支持模擬器設(shè)備,對(duì)于真機(jī)設(shè)備,我們需要選中Generic iOS Device進(jìn)行編譯,最終得到支持真機(jī)設(shè)備運(yùn)行的靜態(tài)庫(kù)。

各種不同機(jī)型設(shè)備的架構(gòu)如下表所舉:

各種不同機(jī)型設(shè)備的架構(gòu).png

如果靜態(tài)庫(kù)里面有資源文件怎么辦?
Tips as follows:
如果靜態(tài)庫(kù)需要放入資源文件,非常不建議直接將這些資源文件放入靜態(tài)庫(kù)路徑下不做任何處理。  最合理的方法:將存放這些資源的文件夾改名為resource.bundle(一定要是.bundle)。這樣在項(xiàng)目中導(dǎo)入靜態(tài)庫(kù)的時(shí)候,一起導(dǎo)入resource.bundle文件(好處是在編譯生成xxx.app文件的時(shí)候,工程資源文件如果與靜態(tài)庫(kù)資源文件有重名,也不會(huì)覆蓋其中任一方的資源文件,以后就這么做)。

多種架構(gòu)靜態(tài)庫(kù)的合成與分解

1.合成靜態(tài)庫(kù)文件

對(duì)于模擬器和真機(jī)設(shè)備,編譯之后得到兩份靜態(tài)庫(kù)。通過(guò)"lipo -create Debug-iphonesimulator.a(路徑) Debug-iphoneos(路徑) -output xxx.a"命令在終端合成最終的靜態(tài)庫(kù)文件xxx.a。合成之后的xxx.a即能支持模擬器,又可以支持真機(jī)。

Rephontil:Debug-iphoneos zhouyong$ cd /Users/zhouyong/Library/Developer/Xcode/DerivedData/StaticLib-ccrfruuotxbhdydkrcdebfkcvqwp/Build/Products/CombineLibrary 
Rephontil:CombineLibrary zhouyong$ lipo -create /Users/zhouyong/Library/Developer/Xcode/DerivedData/StaticLib-ccrfruuotxbhdydkrcdebfkcvqwp/Build/Products/Debug-iphoneos/libStaticLib.a /Users/zhouyong/Library/Developer/Xcode/DerivedData/StaticLib-ccrfruuotxbhdydkrcdebfkcvqwp/Build/Products/Debug-iphonesimulator/libStaticLib.a -output libStaticLib.a
注意

由于合成以后靜態(tài)庫(kù)文件的體積是之前支持模擬器和支持真機(jī)靜態(tài)庫(kù)文件的總和,如果靜態(tài)庫(kù)體積本身就很大,合成模擬器和真機(jī)環(huán)境的靜態(tài)庫(kù)就顯得不明智了。開(kāi)發(fā)者自己選擇打包的時(shí)候需要包含的靜態(tài)庫(kù)即可。

2.靜態(tài)庫(kù)廋身
如果合成之后的靜態(tài)庫(kù)支持i386 arm64 x86等架構(gòu),但是我們只想要i386這一種架構(gòu),可以通過(guò)“l(fā)ipo -thin  -output”命令將之前合成的fat靜態(tài)庫(kù)瘦身成只支持i386架構(gòu)的庫(kù)(也就是同時(shí)移除了arm64 x86兩種架構(gòu)),thin指令具體操作如下:
lipo -thin i386  庫(kù)的路徑  -output 新的庫(kù)名

另外:如果我們只是希望從合成的庫(kù)中移除i386架構(gòu),保留arm64 x86兩種架構(gòu),則可以通過(guò)“l(fā)ipo  -remove  -output”指令單獨(dú)移除某一種架構(gòu)。remove指令具體操作如下:
lipo -remove i386  庫(kù)的路徑  -output 新的庫(kù)名

<2> Cocoa Touch Framework中 .framework類(lèi)型的靜態(tài)庫(kù)

為了方便靜態(tài)庫(kù)的測(cè)試,我們先創(chuàng)建一個(gè)iOS項(xiàng)目,然后再在項(xiàng)目中創(chuàng)建一個(gè)靜態(tài)庫(kù)。

項(xiàng)目中創(chuàng)建靜態(tài)庫(kù)步驟.jpg

按照?qǐng)D中步驟,我們便可創(chuàng)建一個(gè).framework類(lèi)型的庫(kù)。

注意:
①由于默認(rèn)情況下生成的.framework庫(kù)是動(dòng)態(tài)的,需要在Build Settings里設(shè)置mach為Static Library。
②設(shè)置Build Active Architecture Only 為NO,以導(dǎo)出支持多種架構(gòu)庫(kù)。
③設(shè)置.framework暴露出來(lái)的頭文件。

framework類(lèi)型靜態(tài)庫(kù)導(dǎo)出設(shè)置圖解.jpg
添加需要暴露的頭文件.png

通過(guò)show in finder查看生成的靜態(tài)庫(kù)文件。

生成的靜態(tài)庫(kù)文件.png

將生成的靜態(tài)庫(kù)文件拖入新的項(xiàng)目中,便可使用。需要注意的是引入頭文件的方式有所變化。格式為:“#import <.framework庫(kù)名/xxx.h>”

使用.framework靜態(tài)庫(kù).png

圖片發(fā)自簡(jiǎn)書(shū)App
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別 首先來(lái)看什么是庫(kù),庫(kù)(Library)說(shuō)白了就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別...
    吃瓜群眾呀閱讀 12,336評(píng)論 3 42
  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱(chēng)項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,213評(píng)論 3 119
  • 記得前段時(shí)間有一個(gè)風(fēng)靡朋友圈的小測(cè)試--2018你靠什么吃飯?我那時(shí)測(cè)試的結(jié)果是 2018,我靠技...
    崔嘉芯閱讀 459評(píng)論 2 8
  • 本來(lái)想著,正式跨入2017的時(shí)候?qū)憗?lái)著,但是去男票那兒玩了,有點(diǎn)懶,就拖到了現(xiàn)在。把自己過(guò)去的一年里,干的哪些改變...
    桃枝夭妖閱讀 486評(píng)論 0 0

友情鏈接更多精彩內(nèi)容