iOS中庫的相關(guān)概念
- 庫: 就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別人使用了
- 庫的分類:開源庫和閉源庫的形式
- 開源庫如:AFNetworking, 源碼一般放在某個版本控制庫中
- 很多人直接下載開源代碼,將相關(guān)文件copy到自己的工程,直接使用,缺點(diǎn)是當(dāng)開源庫的版本更新后,還要在手動copy一次,比較麻煩
- 使用git的submodule
- 現(xiàn)在比較常用的是cocoapods,用命令導(dǎo)入開源庫,而且不用關(guān)心開源庫的相關(guān)依賴。cocoapods的本質(zhì)是將公用庫編譯成靜態(tài)庫,然后使得主工程依賴此靜態(tài)庫
- 開源庫如:AFNetworking, 源碼一般放在某個版本控制庫中
- 閉源庫
- 用途: 某些代碼需要給別人使用,但是又不希望給被人看到源碼,就需要以庫的形式進(jìn)行封裝,只暴露出頭文件
- 對某些不會進(jìn)行大的改動的代碼,我們想要減少編譯的時間,就可以打包成庫,因為庫是已經(jīng)編譯好的二進(jìn)制文件了,編譯的時候Link一下就可以了,不會浪費(fèi)編譯時間。
- 根據(jù)使用庫Link的方式,閉源庫可以分為靜態(tài)庫和動態(tài)庫
- 靜態(tài)庫:(.a或者.framework )在編譯的時候會被直接copy一份,復(fù)制到目標(biāo)程序里,在編譯完成之后,庫文件實(shí)際就沒有多大作用了,目標(biāo)程序沒有外部依賴,可以直接運(yùn)行,缺點(diǎn)是(目標(biāo)程序的體積會增大)
- .a格式的靜態(tài)庫,一般使用的時候需要提供.h .a .bundle文件,由于創(chuàng)建靜態(tài)庫項目的時候編譯出來的靜態(tài)庫只支持特定的一種硬件架構(gòu)體系,所以如果需要生成通用靜態(tài)庫,需要用到lipo命令將多個靜態(tài)庫合并。
- .framework格式的靜態(tài)庫,framework最終只是一個bundle(一個文件夾,里面按照規(guī)定的目錄結(jié)構(gòu)方式文件),但是對XCode而言這樣的target還是有真假(Real/Fake)之分,只有真的情況下XCode主工程在添加依賴的時候才能夠選擇此公用庫項目的framework漲的target
- 動態(tài)庫:在編譯時不會被copy盜目標(biāo)程序,目標(biāo)程序只會存儲指向動態(tài)庫的引用,等到程序運(yùn)行時,動態(tài)庫才會被真正加載進(jìn)來。不會影響目標(biāo)程序的體積,但是會帶來一部分性能損失。蘋果不允許自制動態(tài)庫上架到appstore
iOS中.a靜態(tài)庫的制作
-
新建XCode中的lib工程如下圖所示:
buildLib -
將靜態(tài)庫作為子項目引用到其他工程
UseLib
<p>注:引用靜態(tài)庫的工程的Target Dependencies和Link Binary With Libraries均需要添加.a靜態(tài)庫</p>
<p style ="text-indent:2em">引用靜態(tài)庫的工程,需要在Header Search Paths中添加靜態(tài)庫項目的頭文件的路徑(".."表示返回上層目錄)</p>
<p style ="text-indent:2em">制作的靜態(tài)庫中如果添加了分類,引用靜態(tài)庫的工程需要在Other linker Flags中添加-ObjC</p>
- 編譯靜態(tài)庫
-
編譯靜態(tài)庫項目中的所有文件:
compileLib - 編譯靜態(tài)庫項目中的部分文件:
[圖片上傳失敗...(image-86e6c0-1519910623969)]
<p>注:當(dāng)只需要打包部分文件時,只需要在打包靜態(tài)庫的工程里面不需要打包的.m文件的Taget MemberShip中的勾選去掉,則該文件將不會被打包到靜態(tài)庫中去</p>
<p style ="text-indent:2em">查看自己打包的靜態(tài)庫都包含了哪些文件可以用lipo命令</p>
- lipo 命令的用法
- 查看靜態(tài)庫中包含哪些架構(gòu)
lipo -info lib.a - 合并模擬器庫文件和真機(jī)庫文件
lipo -create -output lib.a lib-armv6.a lib-i386.a
- 解壓出指定架構(gòu)的靜態(tài)庫
lipo -extract_family armv7 -output lib-armv7.a lib.a
或者
lipo lib.a -thin armv7 -output lib-armv7.a
- 將a格式的靜態(tài)庫解壓為o文件,可以解壓出所有的.o文件
ar -x lib.a
- 將o文件合并為a文件
libtool -static -o lib.a *.o
靜態(tài)庫中的注意事項
- 靜態(tài)庫所依賴的dylib或者framework,最終使用靜態(tài)庫的程序也需要引用
- 靜態(tài)庫是二進(jìn)制代碼,區(qū)分處理器類型的,可以使用lipo -create –output創(chuàng)建支持多處理器的靜態(tài)庫
- 靜態(tài)庫中使用的開源代碼與引用靜態(tài)庫的工程使用的開源代碼相同時,將會出現(xiàn)沖突.
- 解決1: 靜態(tài)庫不打包相關(guān)的開源代碼,在靜態(tài)庫使用說明文檔中列出所依賴的開源庫及其版本
- 解決2: 靜態(tài)庫在打包開源代碼時,修改開源代碼的類的命名加上三個字母以上的前綴(不建議)
- 對于已經(jīng)打包好的靜態(tài)庫,可以利用lipo命令解包其中一個靜態(tài)庫,然后把發(fā)生沖突的.o文件刪除,然后lipo命令重新打包,然后對每種處理器框架的.a文件重復(fù)操作,最后lipo重新合并靜態(tài)庫,替換原來的靜態(tài)庫
- a.靜態(tài)庫中的類的命名與引用靜態(tài)庫的工程的類的命名相同時將會被視為重復(fù)定義(OC沒有命名空間導(dǎo)致)
- 解決:靜態(tài)庫中的類命名加上三個字母以上的前綴
- 靜態(tài)庫中使用Category,用Category添加的方法即使名字重復(fù) 了也不會報錯,但是會存在其中一個方法覆蓋了另一個
- 解決: 建議給category添加的方法添加前綴
- 全局變量重名是必然編譯失敗的
- 解決:給靜態(tài)庫中用到的全局變量加前綴
- 靜態(tài)庫中有可能會使用debug時打開log,release關(guān)閉log,發(fā)布到Appstore的應(yīng)用不應(yīng)該把調(diào)試的log打印出來,因此,在打包靜態(tài)庫時,把Build Configuration選擇為Release一般可以把多數(shù)開源庫的log都去掉了,如果靜態(tài)庫使用者希望能在開發(fā)時看到log,這時就看不到了
- 解決:分開打debug和release的包


