-
腦補(bǔ)一下:
- 預(yù)處理:預(yù)處理相當(dāng)于根據(jù)預(yù)處理命令組裝成新的C程序,不過常以i為擴(kuò)展名盹舞。
- 編譯: 將得到的i文件翻譯成匯編代碼产镐。s文件。
- 匯編: 將匯編文件翻譯成機(jī)器指令踢步,并打包成可重定位目標(biāo)程序的O文件癣亚。該文件是二進(jìn)制文件,字節(jié)編碼是機(jī)器指令获印。
- 鏈接: 將引用的其他O文件并入到我們程序所在的o文件中述雾,處理得到最終的可執(zhí)行文件。
靜態(tài)庫&&動(dòng)態(tài)庫
庫分為靜態(tài)庫和動(dòng)態(tài)庫兩類兼丰。在動(dòng)態(tài)庫里玻孟,又分為動(dòng)態(tài)鏈接庫和動(dòng)態(tài)加載庫。
動(dòng)態(tài)庫
對(duì)于動(dòng)態(tài)鏈接庫而言鳍征,build可執(zhí)行文件的時(shí)候需要指定它依賴哪些庫黍翎,當(dāng)可執(zhí)行文件運(yùn)行時(shí),如果操作系統(tǒng)沒有加載過這些庫蟆技,那就會(huì)把這些庫隨著可執(zhí)行文件的加載而加載進(jìn)內(nèi)存中玩敏,供可執(zhí)行程序運(yùn)行斗忌。如果多個(gè)可執(zhí)行文件依賴同一個(gè)動(dòng)態(tài)鏈接庫质礼,那么內(nèi)存中只會(huì)有一份動(dòng)態(tài)鏈接庫的代碼旺聚,然后把它共享給所有相關(guān)可執(zhí)行文件的進(jìn)程使用,所以它也叫共享庫(shared library)眶蕉。比如pthread就是一個(gè)這樣的庫砰粹。
對(duì)于動(dòng)態(tài)加載庫而言,build可執(zhí)行文件的時(shí)候就不需要指定它依賴哪些庫造挽,當(dāng)可執(zhí)行文件運(yùn)行時(shí)碱璃,如果需要加載某個(gè)庫,就用dlopen饭入、dlsym嵌器、dlclose等函數(shù)來動(dòng)態(tài)地把庫加載到內(nèi)存,并調(diào)用庫里面的函數(shù)谐丢。各大軟件的插件模塊基本上就都是這樣的庫爽航。事實(shí)上,靜態(tài)庫和動(dòng)態(tài)鏈接庫也可以被動(dòng)態(tài)加載乾忱,只是由于使用方式的不同讥珍,才多了一個(gè)動(dòng)態(tài)加載庫這樣的類別。
linux中靜態(tài)庫和動(dòng)態(tài)庫區(qū)別:
庫從本質(zhì)上來說是一種可執(zhí)行代碼的二進(jìn)制格式窄瘟,可以被載入內(nèi)存中執(zhí)行衷佃。庫分靜態(tài)庫和動(dòng)態(tài)庫兩種。
- 靜態(tài)庫:這類庫的名字一般是
libxxx.a蹄葱;
利用靜態(tài)函數(shù)庫編譯成的文件比較大氏义,因?yàn)檎麄€(gè)函數(shù)庫的所有數(shù)據(jù)都會(huì)被整合進(jìn)目標(biāo)代碼中,他的優(yōu)點(diǎn)就顯而易見了图云,即編譯后的執(zhí)行程序不需要外部的函數(shù)庫支持惯悠,因?yàn)樗惺褂玫暮瘮?shù)都已經(jīng)被編譯進(jìn)去了。當(dāng)然這也會(huì)成為他的缺點(diǎn)琼稻,因?yàn)槿绻o態(tài)函數(shù)庫改變了吮螺,那么你的程序必須重新編譯。 - 動(dòng)態(tài)庫:這類庫的名字一般是
libxxx.so;
相對(duì)于靜態(tài)函數(shù)庫帕翻,動(dòng)態(tài)函數(shù)庫在編譯的時(shí)候 并沒有被編譯進(jìn)目標(biāo)代碼中鸠补,你的程序執(zhí)行到相關(guān)函數(shù)時(shí)才調(diào)用該函數(shù)庫里的相應(yīng)函數(shù),因此動(dòng)態(tài)函數(shù)庫所產(chǎn)生的可執(zhí)行文件比較小嘀掸。由于函數(shù)庫沒有被整合進(jìn)你的程序紫岩,而是程序運(yùn)行時(shí)動(dòng)態(tài)的申請(qǐng)并調(diào)用,所以程序的運(yùn)行環(huán)境中必須提供相應(yīng)的庫睬塌。動(dòng)態(tài)函數(shù)庫的改變并不影響你的程序泉蝌,所以動(dòng)態(tài)函數(shù)庫的升級(jí)比較方便歇万。
iOS開發(fā)中靜態(tài)庫和動(dòng)態(tài)庫區(qū)別
- 1.靜態(tài)庫和動(dòng)態(tài)庫是相對(duì)編譯期和運(yùn)行期的:
- 2.靜態(tài)庫在程序編譯時(shí)會(huì)被鏈接到目標(biāo)代碼中,程序運(yùn)行時(shí)將不再需要改靜態(tài)庫勋陪;
- 3.而動(dòng)態(tài)庫在程序編譯時(shí)并不會(huì)被鏈接到目標(biāo)代碼中贪磺,只是在程序運(yùn)行時(shí)才被載入,因?yàn)樵诔绦蜻\(yùn)行期間還需要?jiǎng)討B(tài)庫的存在诅愚。
優(yōu)劣對(duì)比
靜態(tài)庫優(yōu)點(diǎn):
- i.模塊化寒锚,分工合作,提高了代碼的復(fù)用及核心技術(shù)的保密程度违孝。
- ii.避免少量改動(dòng)經(jīng)常導(dǎo)致大量的重復(fù)編譯連接刹前。
- iii.也可以重用,注意不是共享使用雌桑。
動(dòng)態(tài)庫優(yōu)點(diǎn):
- i.使用動(dòng)態(tài)庫喇喉,可以將最終可執(zhí)行文件體積縮小,將整個(gè)應(yīng)用程序分模塊校坑,團(tuán)隊(duì)合作拣技,進(jìn)行分工,影響比較小撒踪。
- ii.使用動(dòng)態(tài)庫过咬,多個(gè)應(yīng)用程序共享內(nèi)存中得同一份庫文件,節(jié)省資源制妄。
- iii.使用動(dòng)態(tài)庫掸绞,可以不重新編譯連接可執(zhí)行程序的前提下,更新動(dòng)態(tài)庫文件達(dá)到更新應(yīng)用程序的目的耕捞。
- iv.應(yīng)用插件化:這個(gè)牛逼
- v.軟件版本實(shí)時(shí)模塊升級(jí)
- vi.共享可執(zhí)行文件 在其它大部分平臺(tái)上衔掸,動(dòng)態(tài)庫都可以用于不同應(yīng)用間共享,這就大大節(jié)省了內(nèi)存俺抽。從目前來看敞映,
iOS
仍然不允許進(jìn)程間共享動(dòng)態(tài)庫,即iOS
上的動(dòng)態(tài)庫只能是私有的磷斧,因?yàn)槲覀內(nèi)匀徊荒軐?dòng)態(tài)庫文件放置在除了自身沙盒以外的其它任何地方振愿。不過iOS8
上開放了App Extension功能,可以為一個(gè)應(yīng)用創(chuàng)建插件弛饭,這樣主app和插件之間共享動(dòng)態(tài)庫還是可行的冕末。
Xcode中.framework和.a
語言支持情況
庫類型/語言類型 | OC | Swift |
---|---|---|
靜態(tài)庫 | iOS7+ | 不支持 |
動(dòng)態(tài)庫 | iOS8+ | iOS8+ |
使用Swift開發(fā)動(dòng)態(tài)庫的方式提供SDK,所以只能支持到iOS8+侣颂。但這意味著所有使用我的SDK的客戶的APP都必須到iOS8+档桃,這點(diǎn)需要斟酌一下。
所以假如需要支持iOS7的話憔晒,只有使用OC語言開發(fā).a靜態(tài)庫的一條路藻肄。
集成第三方庫
原本SDK已經(jīng)作為別人APP工程里的第三方了蔑舞,假如SDK中需要引用AFNetworking類似的三方庫。
庫類型/引用 | 內(nèi)部引用 | 外部引用 |
---|---|---|
靜態(tài)庫 | 靜態(tài)庫無法再包含其他的.a靜態(tài)庫嘹屯。只能把源碼放進(jìn)去一起編譯攻询。 | 靜態(tài)庫無法把第三方放在外部,否則就不叫“靜態(tài)”了抚垄。只能打包進(jìn)SDK內(nèi)部蜕窿,并修改類名谋逻,防止外部沖突呆馁。 |
動(dòng)態(tài)庫 | 如果用Swift 可以直接引入源碼,由于Swift 含有命名空間毁兆,所以不會(huì)有沖突浙滤。 |
第三方庫不打進(jìn)去,放在外部气堕,比如cocoapods 的方式纺腊。別人編譯的時(shí)候需要在他的環(huán)境里有該第三方依賴庫。當(dāng)提供給別人SDK的時(shí)候茎芭,你還需要給別人一個(gè)podfile揖膜。
|
創(chuàng)建靜態(tài)庫
-
1、創(chuàng)建靜態(tài)庫工程
-
2梅桩、創(chuàng)建靜態(tài)庫文件
-
3壹粟、將頭文件暴露出來:將頭文件添加到Copy Files中去
-
4、編譯靜態(tài)庫:注意:需要修改
Build Settings
中的Build Active Architecture Only
以滿足運(yùn)行不同CPU環(huán)境的模擬器宿百。 將此設(shè)置為NO趁仙。
在不同編譯環(huán)境下編譯會(huì)生成四種靜態(tài)庫,debug模擬器垦页,debug真機(jī)雀费,release模擬器,release真機(jī)痊焊,我們需要將運(yùn)行環(huán)境調(diào)至不同的狀態(tài)并生成如上四種形式的靜態(tài)庫盏袄。
5、最后不要忘了按住
command+b
編譯氨∩丁T稹(分別在模擬器和真機(jī)的環(huán)境下編譯才能生成所對(duì)應(yīng)環(huán)境的靜態(tài)庫)-
6、你會(huì)看到如下四個(gè)目錄罪佳,這個(gè)就成功啦
查看靜態(tài)庫所支持的CPU環(huán)境
每一個(gè)手機(jī)都有屬于自己的架構(gòu)逛漫,不同CPU采用的是不同的CPU架構(gòu)。 任何一個(gè)靜態(tài)庫都有它支持的CPU架構(gòu)赘艳,如果是跑在不支持的CPU架構(gòu)上面酌毡,那么就會(huì)報(bào)錯(cuò)克握。比如基于iPhone 6sPlus的架構(gòu)來創(chuàng)建的靜態(tài)庫,如果運(yùn)行在4s上 就會(huì)報(bào)錯(cuò)枷踏。
修改
Build Settings -- >Build Active Architecture Only
為NO
就解決了這個(gè)問題原茅。
在終端中使用 lipo -info
靜態(tài)庫文件 查看文件支持的運(yùn)行環(huán)境
合并靜態(tài)庫
lipo -create 靜態(tài)庫1 靜態(tài)庫2 -output 新靜態(tài)庫名稱.a
最后
使用靜態(tài)庫
靜態(tài)庫使用中的一些注意點(diǎn)
如果直接拖拽的是一個(gè)項(xiàng)目柏副,并將項(xiàng)目當(dāng)做一個(gè)靜態(tài)庫引用需要這樣處理:在
Build Phases
中的Target Dependencies
和Link Binary With Libraries
中分別添加項(xiàng)目。如果僅僅是一個(gè)靜態(tài)庫的話,那么
Link Binary WithLibraries
是必須添加的龟虎。如果編譯的靜態(tài)庫中有分類的話必須在
Build Settings --> Other Linker Flags
中加 -Objc 如果還崩潰,還得加上-all_load
關(guān)于在靜態(tài)庫中添加資源敛助,一般使用的是
bundle
文件夾叨粘,如何創(chuàng)建呢?很簡單先創(chuàng)建一個(gè)文件夾旗芬,然后將所需資源扔進(jìn)去舌胶,最后將文件夾名稱加上后綴bundle
就ok了。注意疮丛,默認(rèn)的靜態(tài)庫編輯是不會(huì)將bundle一起編譯進(jìn)去的幔嫂,所以這個(gè)文件夾需要我們手動(dòng)添加到使用靜態(tài)庫的工程中去。
動(dòng)態(tài)庫
1誊薄、制作履恩、編譯的過程與靜態(tài)庫相同,只不過創(chuàng)建工程的時(shí)候選擇的是framework庫呢蔫。
-
2切心、注意:動(dòng)態(tài)庫可以使用但是不能上架! 而且使用的時(shí)候必須在添加動(dòng)態(tài)庫的工程中的
General-->Embedded Binaries
中添加一下咐刨,具體如圖所示:
-
3昙衅、那么如何想使用動(dòng)態(tài)庫上架呢? 我們只需要在制作的時(shí)候?qū)⑵渚幾g成靜態(tài)庫定鸟。在
Buid Settins-->Mach-O Type--> Static Library
具體如圖
動(dòng)態(tài)庫的查看與合并
這里有個(gè)注意點(diǎn)就是而涉,我們所要查看和合并的并不是xxx.framework
,而是xxx.framework
目錄下的xxx
联予,以下圖為例啼县,我們想要查看或合并的文件就是libframework
,對(duì)這個(gè)文件進(jìn)行操作就可以了沸久。
參考
制作篇
iOS XCode7制作.Framework動(dòng)態(tài)庫和.a靜態(tài)庫的總結(jié)
iOS:Xcode7下創(chuàng)建 .a靜態(tài)庫 和 .framework靜態(tài)庫
使用Swift打造動(dòng)態(tài)庫SDK和DemoAPP時(shí)所遇到的(Xcode7.3)
Xcode創(chuàng)建靜態(tài)庫和動(dòng)態(tài)庫
iOS - 靜態(tài)庫與動(dòng)態(tài)庫的制作
原理篇