一、簡單介紹
1.什么是庫?
庫是程序代碼的集合奋姿,是共享程序代碼的一種方式
2.庫的分類
根據(jù)源代碼的公開情況逸尖,庫可以分為2種類型
(1)開源庫
公開源代碼古沥,能看到具體實(shí)現(xiàn)
比如SDWebImage瘸右、AFNetworking
(2)閉源庫
不公開源代碼,是經(jīng)過編譯后的二進(jìn)制文件岩齿,看不到具體實(shí)現(xiàn)
主要分為:靜態(tài)庫太颤、動態(tài)庫
二、靜態(tài)庫和動態(tài)庫
1.靜態(tài)庫和動態(tài)庫的存在形式
靜態(tài)庫:.a 和 .framework
動態(tài)庫:.dylib 和 .framework
2.靜態(tài)庫和動態(tài)庫在使用上的區(qū)別
靜態(tài)庫:鏈接時(shí)盹沈,靜態(tài)庫會被完整地復(fù)制到可執(zhí)行文件中龄章,被多次使用就有多份冗余拷貝(圖1所示)
動態(tài)庫:鏈接時(shí)不復(fù)制,程序運(yùn)行時(shí)由系統(tǒng)動態(tài)加載到內(nèi)存乞封,供程序調(diào)用做裙,系統(tǒng)只加載一次,多個(gè)程序共用肃晚,節(jié)省內(nèi)存(圖2所示)
圖1
![](http://images.cnitblog.com/i/450136/201408/051917280067546.png)
圖2
![](http://images.cnitblog.com/i/450136/201408/051917367091539.png)
注意點(diǎn):項(xiàng)目中如果使用了自制的動態(tài)庫锚贱,不能被上傳到AppStore
三、靜態(tài)庫的制作(.a)
(1)選擇“Cocoa Touch Static Library”
![](http://images.cnitblog.com/i/450136/201408/051919285226765.png)
(2)輸入靜態(tài)庫名稱(以MJRefresh為例)
![](http://images.cnitblog.com/i/450136/201408/051931251158154.png)
(3)刪除自動生成的文件
![](http://images.cnitblog.com/i/450136/201408/051931442561469.png)
(4)添加庫需要包含的源代碼
![](http://images.cnitblog.com/i/450136/201408/051931573656207.png)
![](http://images.cnitblog.com/i/450136/201408/051932141786078.png)
注意:資源文件是不能打包到.a文件中的关串。
(5)選擇需要暴露出來的.h文件拧廊,.m文件會自動編譯到.a文件中
![](http://images.cnitblog.com/i/450136/201408/051936447871450.png)
添加,并選擇需要暴露的頭文件
![](http://images.cnitblog.com/i/450136/201408/051937022729691.png)
![](http://images.cnitblog.com/i/450136/201408/051938369439247.png)
設(shè)置(移動)為公開的悍缠。
![](http://images.cnitblog.com/i/450136/201408/051939129901460.png)
(6)選擇真機(jī)設(shè)備卦绣,然后 Command+B 編譯,libMJRefresh.a文件從紅色變?yōu)楹谏?/p>
這個(gè)時(shí)候飞蚓,程序會報(bào)錯(cuò)滤港,因?yàn)榭蚣苤邪薈GFloat,它是UIKit里面的東西趴拧,因此可以在pch文件中包含UIKit框架溅漾。
![](http://images.cnitblog.com/i/450136/201408/051942100534421.png)
再次進(jìn)行編譯,編譯成功后生成的.a文件就是靜態(tài)庫著榴。
(7)選擇模擬器添履,依然 Command+B ,模擬器和真機(jī)環(huán)境下用的.a文件是分開的
![](http://images.cnitblog.com/i/450136/201408/051945531009829.png)
(8)右擊“Show In Finder”脑又,查看制作好的.a文件
![](http://images.cnitblog.com/i/450136/201408/051946555686347.png)
![](http://images.cnitblog.com/i/450136/201408/051947153505491.png)
說明:
Debug-iphoneos文件夾里面的東西是用在真機(jī)上的
Debug-iphonesimulator文件夾里面的東西是用在模擬器上的
如果Scheme是Release模式暮胧,生成的文件夾就以Release開頭
(9)合并兩個(gè)文件
如果想讓一個(gè).a文件能同時(shí)用在真機(jī)和模擬器上,需要進(jìn)行合并
在終端輸入指令:
lipo -createDebug-iphoneos/libMJRefresh.aDebug-iphonesimulator/libMJRefresh.a-outputlibMJRefresh.a
說明:
藍(lán)色部分是固定指令
紅色问麸、紫色是真機(jī)和模擬器.a文件的路徑
綠色是所合成.a文件的路徑
![](http://images.cnitblog.com/i/450136/201408/051959122879451.png)
生成的文件(靜態(tài)庫)
![](http://images.cnitblog.com/i/450136/201408/051959472406463.png)
提示:
1)文件大小.a文件的體積(一般情況下)
真機(jī)用的.a > 模擬器用的.a
所合成.a == 真機(jī)用的.a + 模擬器用的.a
2).a的類型
通過lipo –info libMJRefresh.a可以查看 .a 的類型(模擬器還是真機(jī))
(10)如何使用.a
直接將.a往衷、.h、資源文件拖拽到其他項(xiàng)目中即可
別人拿到的框架严卖,只有.a文件和暴露出來的頭文件
![](http://images.cnitblog.com/i/450136/201408/052006544757753.png)
注意:如果庫中還包含了一些資源文件(如圖片等)席舍,那么資源文件也應(yīng)該放在上面的文件夾中。
四哮笆、制作靜態(tài)庫的注意點(diǎn)
(1)注意:
無論是 .a 靜態(tài)庫還是 .framework 靜態(tài)庫来颤,最終需要的都是:二進(jìn)制文件 + .h + 其它資源文件
(2).a 和 .framework 的使用區(qū)別
.a 本身是一個(gè)二進(jìn)制文件汰扭,需要配上 .h 和 其它資源文件 才能使用
.framework 本身已經(jīng)包含了 .h 和 其它資源文件,可以直接使用
(3)圖片資源的處理
如果靜態(tài)庫中用到了圖片資源福铅,一般都放到一個(gè)bundle文件中萝毛,bundle名字一般跟 .a 或 .framework 名字一致
bundle的創(chuàng)建:新建一個(gè)文件夾,修改擴(kuò)展名為 .bundle 即可滑黔,右擊bundle文件珊泳,顯示包內(nèi)容,就可以往bundle文件中放東西
建議:自己制作的靜態(tài)庫中要用到的圖片資源,不建議直接以png的后綴名方式拖到項(xiàng)目中使用薯演,而是推薦使用放到bundle文件中撞芍。這樣可以避免靜態(tài)庫的圖片名和使用靜態(tài)庫的項(xiàng)目中存在的圖片產(chǎn)生沖突跨扮。
1)新建一個(gè)文件夾,把需要打包的資源圖片放在里面
![](http://images.cnitblog.com/i/450136/201408/052018477562597.png)
2)修改擴(kuò)展名為?.bundle衡创,敲回車,點(diǎn)擊添加璃氢。
![](http://images.cnitblog.com/i/450136/201408/052021011787026.png)
(4)多文件處理
如果靜態(tài)庫需要暴露出來的 .h 比較多,可以考慮創(chuàng)建一個(gè)主頭文件(一般 主頭文件 和 靜態(tài)庫 同名)
在主頭文件中包含所有其他需要暴露出來的 .h 文件
使用靜態(tài)庫時(shí)一也,只需要#import 主頭文件
實(shí)際上蘋果官方就是這么做的,例如:#import
(5).framework為什么既是靜態(tài)庫又是動態(tài)庫
系統(tǒng)的 .framework 是動態(tài)庫
我們自己建立的 .framework 是靜態(tài)庫
(6)靜態(tài)庫中包含了Category(分類)
如果靜態(tài)庫中包含了Category椰苟,有時(shí)候在使用靜態(tài)庫的工程中會報(bào)“方法找不到”的錯(cuò)誤(unrecognized selector sent to instance)
解決方案:在使用靜態(tài)庫的工程中配置Other Linker Flags為-ObjC
![](http://images.cnitblog.com/i/450136/201408/052012436156884.png)