iOS中靜態庫的使用 – iPhone手機開發 iPhone軟體開發教學課程

iOS中庫的相關概念

庫: 就是一段編譯好的二進制代碼,加上頭文件就可以供別人使用瞭

庫的分類:開源庫和閉源庫的形式

開源庫如:AFNetworking, 源碼一般放在某個版本控制庫中
很多人直接下載開源代碼,將相關文件copy到自己的工程,直接使用,缺點是當開源庫的版本更新後,還要在手動copy一次,比較麻煩 使用git的submodule 現在比較常用的是cocoapods,用命令導入開源庫,而且不用關心開源庫的相關依賴。cocoapods的本質是將公用庫編譯成靜態庫,然後使得主工程依賴此靜態庫 閉源庫 用途: 某些代碼需要給別人使用,但是又不希望給被人看到源碼,就需要以庫的形式進行封裝,隻暴露出頭文件 對某些不會進行大的改動的代碼,我們想要減少編譯的時間,就可以打包成庫,因為庫是已經編譯好的二進制文件瞭,編譯的時候Link一下就可以瞭,不會浪費編譯時間。

根據使用庫Link的方式,閉源庫可以分為靜態庫和動態庫

靜態庫:(.a或者.framework )在編譯的時候會被直接copy一份,復制到目標程序裡,在編譯完成之後,庫文件實際就沒有多大作用瞭,目標程序沒有外部依賴,可以直接運行,缺點是(目標程序的體積會增大) .a格式的靜態庫,一般使用的時候需要提供.h .a .bundle文件,由於創建靜態庫項目的時候編譯出來的靜態庫隻支持特定的一種硬件架構體系,所以如果需要生成通用靜態庫,需要用到lipo命令將多個靜態庫合並。 .framework格式的靜態庫,framework最終隻是一個bundle(一個文件夾,裡面按照規定的目錄結構方式文件),但是對XCode而言這樣的target還是有真假(Real/Fake)之分,隻有真的情況下XCode主工程在添加依賴的時候才能夠選擇此公用庫項目的framework漲的target 動態庫:在編譯時不會被copy盜目標程序,目標程序隻會存儲指向動態庫的引用,等到程序運行時,動態庫才會被真正加載進來。不會影響目標程序的體積,但是會帶來一部分性能損失。蘋果不允許自制動態庫上架到appstore

iOS中.a靜態庫的制作

新建XCode中的lib工程如下圖所示:
buildLibvcbky/u5pLPMPGJyIC8+DQo8aW1nIGFsdD0=”UseLib” src=”/uploadfile/Collfiles/20160408/20160408091719236.gif” title=”\” />

註:引用靜態庫的工程的Target Dependencies和Link Binary With Libraries均需要添加.a靜態庫

引用靜態庫的工程,需要在Header Search Paths中添加靜態庫項目的頭文件的路徑(“..”表示返回上層目錄)

制作的靜態庫中如果添加瞭分類,引用靜態庫的工程需要在Other linker Flags中添加-ObjC

編譯靜態庫
編譯靜態庫項目中的所有文件:
compileLib 編譯靜態庫項目中的部分文件:
compilePartLib

註:當隻需要打包部分文件時,隻需要在打包靜態庫的工程裡面不需要打包的.m文件的Taget MemberShip中的勾選去掉,則該文件將不會被打包到靜態庫中去

查看自己打包的靜態庫都包含瞭哪些文件可以用lipo命令

lipo 命令的用法

查看靜態庫中包含哪些架構

lipo -info lib.a   

合並模擬器庫文件和真機庫文件

 lipo -create -output lib.a lib-armv6.a lib-i386.a  

解壓出指定架構的靜態庫

lipo -extract_family armv7 -output lib-armv7.a lib.a
或者
lipo lib.a -thin armv7 -output lib-armv7.a

將a格式的靜態庫解壓為o文件,可以解壓出所有的.o文件

ar -x lib.a

將o文件合並為a文件

libtool -static -o lib.a *.o

靜態庫中的註意事項

靜態庫所依賴的dylib或者framework,最終使用靜態庫的程序也需要引用 靜態庫是二進制代碼,區分處理器類型的,可以使用lipo -create –output創建支持多處理器的靜態庫 靜態庫中使用的開源代碼與引用靜態庫的工程使用的開源代碼相同時,將會出現沖突.
解決1: 靜態庫不打包相關的開源代碼,在靜態庫使用說明文檔中列出所依賴的開源庫及其版本 解決2: 靜態庫在打包開源代碼時,修改開源代碼的類的命名加上三個字母以上的前綴(不建議) 對於已經打包好的靜態庫,可以利用lipo命令解包其中一個靜態庫,然後把發生沖突的.o文件刪除,然後lipo命令重新打包,然後對每種處理器框架的.a文件重復操作,最後lipo重新合並靜態庫,替換原來的靜態庫 a.靜態庫中的類的命名與引用靜態庫的工程的類的命名相同時將會被視為重復定義(OC沒有命名空間導致)
解決:靜態庫中的類命名加上三個字母以上的前綴 靜態庫中使用Category,用Category添加的方法即使名字重復 瞭也不會報錯,但是會存在其中一個方法覆蓋瞭另一個
解決: 建議給category添加的方法添加前綴 全局變量重名是必然編譯失敗的
解決:給靜態庫中用到的全局變量加前綴 靜態庫中有可能會使用debug時打開log,release關閉log,發佈到Appstore的應用不應該把調試的log打印出來,因此,在打包靜態庫時,把Build Configuration選擇為Release一般可以把多數開源庫的log都去掉瞭,如果靜態庫使用者希望能在開發時看到log,這時就看不到瞭
解決:分開打debug和release的包

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *