知識儲備:
一.庫(Library)
什么是庫隧哮?
庫是程序代碼的集合羽历,是程序共享代碼的一種方式。根據(jù)源代碼的公開情況港令,庫可以分為開源庫和閉源庫代嗤。比如SDWebImage,AFNetworking,等可以看源碼的叫開源庫。閉源庫缠借,不公開源代碼干毅,是經(jīng)過編譯后的二進制文件,看不到具體的實現(xiàn)泼返。閉源庫又可以分為靜態(tài)庫和動態(tài)庫硝逢。庫說白了就是一段編譯好的二進制代碼,加上頭文件就可以供別人使用。
二.靜態(tài)庫和動態(tài)庫
和多數(shù)人所熟悉的動態(tài)語言和靜態(tài)語言一樣渠鸽,這里的所謂靜態(tài)和動態(tài)是相對編譯期和運行期的
存在形式
靜態(tài)庫:.a 和 .framework ? ?動態(tài)庫: .dylib 和 .framework叫乌。 所以很多人誤以為.a就是靜態(tài)庫,.framework就是動態(tài)庫徽缚,不過系統(tǒng)的.framework都是動態(tài)庫
靜態(tài)庫和動態(tài)庫使用上的區(qū)別
靜態(tài)庫:鏈接時憨奸,靜態(tài)庫會被完整地復制到可執(zhí)行文件中,被多次使用就有多份冗余拷貝凿试。編譯完成后排宰,庫文件實際上就沒有作用了,也這是它的優(yōu)勢那婉。當然其缺點也很明顯板甘,就是會明顯增大程序的體積。
動態(tài)庫:鏈接時不復制详炬,程序運行時由系統(tǒng)動態(tài)加載到內存盐类,供程序調用,系統(tǒng)只加載一次呛谜,供多個程序調用在跳,節(jié)省內存。由此可見動態(tài)庫又可以叫共享庫隐岛。注意:ios 8之前蘋果禁止iOS開發(fā)中使用自己創(chuàng)建的動態(tài)庫硬毕。原因估計是現(xiàn)在的iPhone,iPodTouch礼仗,iPad上面程序都是單進程的吐咳,也就是某一時刻只有一個進程在運行,那么你寫個共享庫元践,共享給誰呢韭脊?你使用的時候只有你一個應用程序存在,其他的應該被掛起了单旁,即便是可以同時多個進程運行沪羔,別人能使用你的共享庫里的東西嗎?但是iOS8之后象浑,出現(xiàn)了Extension蔫饰,動態(tài)庫有了用武之地,而且swift只支持動態(tài)庫的使用愉豺,造成這個原因主要是swift的運行庫沒有被包含在iOS系統(tǒng)中篓吁,而是會被打包進App中(這也是造成Swift App體積大的原因),靜態(tài)庫會導致最終的目標程序中包含重復的運行庫(這是蘋果自家的解釋)蚪拦。
共同點:靜態(tài)庫和動態(tài)庫都是閉源庫杖剪,只能拿來滿足某個功能的使用冻押,不會暴露內部具體的代碼信息,而從github上下載的第三方庫大多是開源庫
三.注意:
1.兩種庫都有framework的格式盛嘿,但是它們長得一樣嗎洛巢?
2.當你創(chuàng)建一個framework文件時,系統(tǒng)“默認”是一個動態(tài)庫的格式次兆,如果想做成靜態(tài)庫稿茉,需要在buildSetting中將Mach-O Type選項設置為Static Library就行了!
3. .a文件和.framework文件組成的區(qū)別:
.a文件是一個純二進制文件芥炭,不能直接拿來使用漓库,需要配合頭文件、資源文件一起使用蚤认。
將靜態(tài)庫打包的時候米苹,只能打包代碼資源糕伐,但是圖片文件砰琢、本地json文件和xib等資源文件無法打包進去,使用.a靜態(tài)庫的時候需要三個組成部分:.a文件+需要暴露的頭文件+資源文件良瞧;
.framework文件內部除了有二進制文件(如下圖黑色文件)之外還有其他的資源文件(相當于:.framwork文件=黑色二進制文件<.a文件+.h文件>+資源文件<圖片陪汽、以及本地的html5,json,plist等),可以直接拿來在工程中使用。
4.制作靜態(tài)庫時需要注意的幾點:
(1)圖片資源的處理:兩種格式的靜態(tài)庫褥蚯,一般都是把圖片文件單獨的放在一個.bundle文件中挚冤,一般.bundle的名字和.a或.framework的名字相同。(.bundle文件很好弄赞庶,在桌面上新建一個文件夾训挡,把它重命名為XXX.bundle就可以了(選中文件->右鍵->顯示包內容->拖拽添加圖片資源))。
(2)category是我們實際開發(fā)項目中經(jīng)常用到的歧强,把category打成靜態(tài)庫是沒有問題的澜薄,但是在使用這個靜態(tài)庫的工程中,調用category中的方法時摊册,會出現(xiàn)找不到該方法的運行時錯誤:selector not recognized肤京,解決辦法是:在使用靜態(tài)庫的工程中配置other linkerflags的值為-ObjC。
(3)如果一個靜態(tài)庫很復雜茅特,需要暴露的.h比較多的話忘分,就可以在靜態(tài)庫的內部創(chuàng)建一個.h文件(一般這個.h文件的名字和靜態(tài)庫的名字相同),然后把所有需要暴露出來的.h文件都集中放在這個.h文件中白修,而那些原本需要暴露的.h都不需要再暴露了妒峦,只需要把.h暴露出來就可以了。
四.實戰(zhàn)制作庫
注:Build active Architecture Only為什么設置為NO兵睛?
在目標設備上舟山,執(zhí)行設備對應的指令集绸狐。Build active Architecture Only 設置為YES,只會選擇編譯累盗、鏈接對應的指令集寒矿,設置為NO時,會涵蓋所有指令集若债,在必要的時候選擇執(zhí)行對應的指令集符相。所以一般在Debug時會選擇設置為YES(效率會高點,雖然也沒什么卵用)蠢琳,Release時會選擇設置為NO啊终,以支持所有可能的架構。
一般供人使用的庫為release版本傲须,這個版本apple會做一些優(yōu)化蓝牲。當Buld Active Archite Only為No時,會編譯所有的版本arm7泰讽、armv7s例衍、arm64。 各種指令集對應的手機為armv7:iPhone 3GS/4/4s ?已卸、armv7s:iPhone5 iPhone5c ?佛玄、arm64:iPhone5s以上、 i386: mac(模擬器)累澡。另外在命令行可以用命令$?lipo?-info?.../XXX.a 來查看庫文件支持的指令集
將靜態(tài)庫分別選擇在模擬器和真機設備中編譯
從圖中可以看到編譯完后有兩個文件夾梦抢,對應著真機和模擬器。接下來我們利用命令 lipo -create XXXX_1.a ?XXXX_2.a -output XXXX_all.a愧哟,將真機和模擬器的庫文件合并奥吩;(前面兩個.a為真機模擬器路徑;后面的為合并后想存放的路徑并為合并后的命名蕊梧,一般名字和之前的一樣)
將.a二進制文件和頭文件放在一起霞赫,靜態(tài)庫就這樣做完了。新建項目拉進去就可以直接使用了望几〖ù啵可能大家有疑問為什么最開始的時候要新建一個project,并是在targets里添加靜態(tài)庫,當然你也可以直接按快捷鍵shift + command + N 來New一個Cocoa Touch Static Library橄抹,進行開發(fā)制作靴迫。但是這樣無法測試你的靜態(tài)庫代碼,無法打斷點調試楼誓;如果你在你的工程里面添加靜態(tài)庫的話可以邊開發(fā)邊調試靜態(tài)庫的玉锌。