Xcode 創(chuàng)建.a和framework靜態(tài)庫(kù)

轉(zhuǎn)載

iOS中的靜態(tài)庫(kù)有 .a 和 .framework兩種形式厚棵;動(dòng)態(tài)庫(kù)有.dylib 和 .framework 形式蕉世,后來(lái).dylib動(dòng)態(tài)庫(kù)又被蘋果替換成.tbd的形式。

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

靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)是相對(duì)編譯期和運(yùn)行期的:靜態(tài)庫(kù)在程序編譯時(shí)會(huì)被鏈接到目標(biāo)代碼中婆硬,程序運(yùn)行時(shí)將不再需要改靜態(tài)庫(kù)狠轻;而動(dòng)態(tài)庫(kù)在程序編譯時(shí)并不會(huì)被鏈接到目標(biāo)代碼中,只是在程序運(yùn)行時(shí)才被載入彬犯,因?yàn)樵诔绦蜻\(yùn)行期間還需要?jiǎng)討B(tài)庫(kù)的存在向楼。

總結(jié):同一個(gè)靜態(tài)庫(kù)在不同程序中使用時(shí)查吊,每一個(gè)程序中都得導(dǎo)入一次,打包時(shí)也被打包進(jìn)去湖蜕,形成一個(gè)程序逻卖。而動(dòng)態(tài)庫(kù)在不同程序中,打包時(shí)并沒(méi)有被打包進(jìn)去昭抒,只在程序運(yùn)行使用時(shí)评也,才鏈接載入(如系統(tǒng)的框架如UIKit、Foundation等)灭返,所以程序體積會(huì)小很多盗迟,但是蘋果不讓使用自己的動(dòng)態(tài)庫(kù),否則審核就無(wú)法通過(guò)熙含。

創(chuàng)建.a靜態(tài)庫(kù)
  • 第一步罚缕,新建工程。一般使用工程名就使用庫(kù)的名稱怎静,比如我這里用FMDB來(lái)創(chuàng)建靜態(tài)庫(kù)邮弹,我的工程名就取名為FMDB,創(chuàng)建的.a靜態(tài)庫(kù)就是libFMDB.a消约。
1468320478754707.jpg
1468320496343210.png
  • 第二步肠鲫,刪除系統(tǒng)默認(rèn)創(chuàng)建的【FMDB.h】和【FMDB.m】文件,導(dǎo)入需要打包的源文件或粮。
QQ截圖20160712184846.png
  • 第三步
    (方式一)导饲,修改項(xiàng)目配置
727768-5d001cd4a0de30dd.jpg

點(diǎn)擊上圖中的【3】,彈出的列表中選擇【New Headers Phase】,打開【Headers (0 items)】氯材,點(diǎn)擊左下角的【+】渣锦,選擇所有的.h文件。

QQ截圖20160712184933.png

(方式二)氢哮,修改項(xiàng)目配置

727768-78d95d4769981bad.jpg
  • 第四步袋毙,修改導(dǎo)出product配置
727768-4188568eec7c43be.jpg
  • 第五步,修改編譯指令集
727768-717773667126f998.jpg

模擬器:iPhone4s~5 : i386 iPhone5s~6plus : x86_64
真機(jī):iPhone3gs~4s : armv7 iPhone5~5c : armv7s iPhone5s~6plus : arm64

如果第五步這里冗尤,設(shè)置為YES听盖,那么編譯出來(lái)的.a靜態(tài)庫(kù)就只包含當(dāng)前設(shè)備的指令集。
舉個(gè)例子:如果我們選擇iPhone 5模擬器【Command+B】編譯裂七,則編譯出來(lái)的.a靜態(tài)庫(kù)只能用iPhone4s5模擬器跑程序皆看,用iPhone5s6plus,則會(huì)報(bào)找不到x86_64的libFMDB庫(kù)背零。
設(shè)置為NO腰吟,則會(huì)把所有指令集的都打包合并!!!!

  • 第六步,編譯(快捷鍵【Command+B】

編譯時(shí)徙瓶,需要用模擬器和真機(jī)各編譯一次毛雇,這樣Products目錄下的libFMDB.a靜態(tài)庫(kù)才會(huì)變?yōu)楹谏党疲益Ishow in Finder,可以進(jìn)入Products目錄下灵疮。

QQ截圖20160712191542.png

為什么需要用模擬器和真機(jī)各編譯一次呢织阅?

可以看到Products目錄下有【Release-iphoneos】和【Release-iphonesimulator】?jī)蓚€(gè)文件件。前者里面是真機(jī)使用的.a靜態(tài)庫(kù)始藕,后者是模擬器使用的.a靜態(tài)庫(kù)蒲稳。

注意:如果步驟四中,不將Build Configuration改為Release,則打包出來(lái)的靜態(tài)庫(kù)會(huì)存于【Debug-iphoneos】和【Debug-iphonesimulator】?jī)蓚€(gè)文件夾下伍派。

我們一般都使用Release模式江耀,因?yàn)槌绦蜃罱K發(fā)布之后是Release版的,所以靜態(tài)庫(kù)也是在Release模式下使用诉植。

如果想要通用需要將模擬器使用的靜態(tài)庫(kù)與真機(jī)使用的靜態(tài)庫(kù)合并成一個(gè)靜態(tài)庫(kù)祥国,可以使用終端命令來(lái)實(shí)現(xiàn)。命令格式:

lipo -create 第一個(gè).a文件的絕對(duì)路徑 第二個(gè).a文件的絕對(duì)路徑 -output 最終的.a文件路徑晾腔。

本文中使用的命令如下:

lipo -create /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-ctegiztcjikewoeprxxtmryzetfa/Build/Products/Release-iphoneos/libFMDB.a /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-ctegiztcjikewoeprxxtmryzetfa/Build/Products/Release-iphonesimulator/libFMDB.a -output /Users/harvey/Desktop/libFMDB.a

補(bǔ)充:經(jīng)過(guò)多次實(shí)踐舌稀,第三步的操作省略,依然可以導(dǎo)出可正常使用的包灼擂。

如果靜態(tài)庫(kù)中有category類壁查,則在使用靜態(tài)庫(kù)的項(xiàng)目配置中【Other Linker Flags】需要添加參數(shù)-ObjC或者-all_load

創(chuàng)建framework靜態(tài)庫(kù)
  • 第一步剔应,新建項(xiàng)目
QQ截圖20160712191641.jpg
  • 第二步睡腿,刪除系統(tǒng)默認(rèn)創(chuàng)建的【FMDB.h】和【FMDB.m】文件,導(dǎo)入需要打包的源文件峻贮。
QQ截圖20160712191717.jpg
  • 第三步席怪,修改項(xiàng)目配置

首先,設(shè)置需要暴漏的頭文件

QQ截圖20160712191747.jpg

這里需要注意的是暴露出來(lái)的頭文件中import的其他類也得添加到public中暴露出來(lái)纤控。

如果不想將import的類暴露出來(lái)挂捻,那么在頭文件中用@class 然后在對(duì)應(yīng)的.m文件中再import。

然后設(shè)置編譯模式船万,在Xcode菜單【Product】--->【Scheme】--->【Edit Scheme...】中

QQ截圖20160712192134.jpg

設(shè)置編譯出的靜態(tài)庫(kù)包含的指令集

QQ截圖20160712192203.jpg

最后修改生成的Mach-O格式

1468322559936793.png
  • 第四步刻撒,編譯生成靜態(tài)庫(kù)

編譯時(shí),需要用模擬器和真機(jī)各編譯一次耿导,這樣Products目錄下的libFMDB.a靜態(tài)庫(kù)才會(huì)變?yōu)楹谏益Ishow in Finder,可以進(jìn)入Products目錄下碎节。

QQ截圖20160712192300.jpg
  • 第五步捧搞,合并模擬器版framework和真機(jī)版framework

合并的命令同上面相似抵卫,不同之處是:framework靜態(tài)庫(kù)合并的不是framework,而是framework下的一個(gè)二進(jìn)制文件狮荔,即上一步圖中標(biāo)記的文件胎撇。

lipo -create 第一個(gè)framework下二進(jìn)制文件的絕對(duì)路徑 第二個(gè)framework下二進(jìn)制文件的絕對(duì)路徑 -output 最終的二進(jìn)制文件路徑。

本文中使用的命令如下:

`lipo -create /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-clvayfrjgytqrbdkyqrtcjkxfeuz/Build/Products/Release-iphonesimulator/FMDB.framework/FMDB /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-clvayfrjgytqrbdkyqrtcjkxfeuz/Build/Products/Release-iphoneos/Release-iphoneos.framework/FMDB -output /Users/harvey/Desktop/FMDB`

最后將任何一個(gè)framework中的二進(jìn)制文件替換成合并后的二進(jìn)制文件即可殖氏。

把framework添加到要使用的項(xiàng)目中即可使用晚树。

注意:

如果創(chuàng)建的framework中使用了category類,則在使用framework的項(xiàng)目配置中【Other Linker Flags】需要添加參數(shù)【-ObjC]或者【-all_load】雅采。

如果使用framework的使用出現(xiàn)【Umbrella header for module 'XXXX' does not include header 'XXXXX.h'】,是因?yàn)殄e(cuò)把xxxxx.h拖到了public中爵憎。

如果出現(xiàn)【dyld: Library not loaded:XXXXXX】,是因?yàn)榇虬膄ramework版本太高婚瓜。比如打包framework時(shí)宝鼓,選擇的是iOS 9.0,而實(shí)際的工程環(huán)境是iOS 8開始的巴刻。

如果創(chuàng)建的framework類中使用了.dylib或者.tbd愚铡,首先需要在實(shí)際項(xiàng)目中導(dǎo)入.dylib或者.tbd動(dòng)態(tài)庫(kù),然后需要設(shè)置【Allow Non-modular Includes ....】為YES胡陪,否則會(huì)報(bào)錯(cuò)"Include of non-modular header inside framework module"沥寥。

QQ截圖20160712192337.jpg

補(bǔ)充:
打包成的靜態(tài)庫(kù)肯定是比源碼類要大很多的,因?yàn)槭怯刹煌噶罴煌O(shè)備的版本合并成的柠座。所以如果你很在意你的app大小邑雅,并且也不是很需要打包成靜態(tài)庫(kù)的話,還是用原始類吧妈经。
framework靜態(tài)庫(kù)中是可以包含圖片資源的淮野;而.a靜態(tài)庫(kù)中不能包含圖片資源,只能另外創(chuàng)建一個(gè)目錄存放狂塘。

填坑記錄

上面的注意里提到了一些坑录煤,以及解決辦法。這里再記錄一些:

1.framework中用到了NSClassFromString荞胡,但是轉(zhuǎn)換出來(lái)的class 一直為nil妈踊。

先來(lái)看一下這個(gè)API的官方描述

QQ截圖20160712192412.png

什么意思呢?如果轉(zhuǎn)換出來(lái)的class為nil泪漂,有兩種情況:一種情況是這個(gè)類不存在廊营;第二種情況是這個(gè)類還沒(méi)有被load。所以一般出現(xiàn)問(wèn)題萝勤,都是第二種情況露筒。

怎么解決這個(gè)問(wèn)題呢?在主工程的【Other Linker Flags】需要添加參數(shù)【-ObjC]即可敌卓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末慎式,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瘪吏,老刑警劉巖癣防,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異掌眠,居然都是意外死亡蕾盯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門蓝丙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)级遭,“玉大人,你說(shuō)我怎么就攤上這事渺尘〈旄耄” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵鸥跟,是天一觀的道長(zhǎng)掠兄。 經(jīng)常有香客問(wèn)我,道長(zhǎng)锌雀,這世上最難降的妖魔是什么蚂夕? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮腋逆,結(jié)果婚禮上婿牍,老公的妹妹穿的比我還像新娘。我一直安慰自己惩歉,他們只是感情好等脂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撑蚌,像睡著了一般上遥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上争涌,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天粉楚,我揣著相機(jī)與錄音,去河邊找鬼亮垫。 笑死模软,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饮潦。 我是一名探鬼主播燃异,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼继蜡!你這毒婦竟也來(lái)了回俐?” 一聲冷哼從身側(cè)響起逛腿,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仅颇,沒(méi)想到半個(gè)月后鳄逾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灵莲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了殴俱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片政冻。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖线欲,靈堂內(nèi)的尸體忽然破棺而出明场,到底是詐尸還是另有隱情,我是刑警寧澤李丰,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布苦锨,位于F島的核電站,受9級(jí)特大地震影響趴泌,放射性物質(zhì)發(fā)生泄漏舟舒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一嗜憔、第九天 我趴在偏房一處隱蔽的房頂上張望秃励。 院中可真熱鬧,春花似錦吉捶、人聲如沸夺鲜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)币励。三九已至,卻和暖如春珊拼,著一層夾襖步出監(jiān)牢的瞬間食呻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工澎现, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搁进,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓昔头,卻偏偏與公主長(zhǎng)得像饼问,于是被迫代替她去往敵國(guó)和親反惕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子噩凹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容