iOS中靜態(tài)庫的使用

iOS中庫的相關(guān)概念

  1. 庫: 就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別人使用了
  2. 庫的分類:開源庫和閉源庫的形式
    • 開源庫如: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)庫
  • 閉源庫
    • 用途: 某些代碼需要給別人使用,但是又不希望給被人看到源碼,就需要以庫的形式進(jìn)行封裝,只暴露出頭文件
    • 對某些不會進(jìn)行大的改動的代碼,我們想要減少編譯的時間,就可以打包成庫,因為庫是已經(jīng)編譯好的二進(jìn)制文件了,編譯的時候Link一下就可以了,不會浪費(fèi)編譯時間。
  1. 根據(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)庫的制作

  1. 新建XCode中的lib工程如下圖所示:


    buildLib
  2. 將靜態(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>

  1. 編譯靜態(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>
  1. 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)庫中的注意事項

  1. 靜態(tài)庫所依賴的dylib或者framework,最終使用靜態(tài)庫的程序也需要引用
  2. 靜態(tài)庫是二進(jìn)制代碼,區(qū)分處理器類型的,可以使用lipo -create –output創(chuàng)建支持多處理器的靜態(tài)庫
  3. 靜態(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)庫
  1. a.靜態(tài)庫中的類的命名與引用靜態(tài)庫的工程的類的命名相同時將會被視為重復(fù)定義(OC沒有命名空間導(dǎo)致)
  • 解決:靜態(tài)庫中的類命名加上三個字母以上的前綴
  1. 靜態(tài)庫中使用Category,用Category添加的方法即使名字重復(fù) 了也不會報錯,但是會存在其中一個方法覆蓋了另一個
  • 解決: 建議給category添加的方法添加前綴
  1. 全局變量重名是必然編譯失敗的
  • 解決:給靜態(tài)庫中用到的全局變量加前綴
  1. 靜態(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的包

引用

iOS常用靜態(tài)庫操作命令

iOS靜態(tài)庫的那些坑

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這幾天公司有一個新的需求,就是要將我們開發(fā)的某些東西都抽取出來,打個比方我們開發(fā)了A項目,可以以后B項目要包含A項...
    黃魚兒啦啦啦閱讀 6,422評論 2 16
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • 靜態(tài)庫與動態(tài)庫的區(qū)別 首先來看什么是庫,庫(Library)說白了就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別...
    吃瓜群眾呀閱讀 12,340評論 3 42
  • 僅以方便自己查閱記錄前言1.靜態(tài)庫和動態(tài)庫有什么異同?靜態(tài)庫:鏈接時完整地拷貝至可執(zhí)行文件中,被多次使用就有多份冗...
    190CM閱讀 4,527評論 0 4
  • 是在秋日午后, 你我相遇, 故事便有了開始; 談不上轟轟烈烈, 卻如煙花, 浪漫而又燦爛地綻開; 劇本臨場發(fā)揮, ...
    2souls閱讀 510評論 0 51

友情鏈接更多精彩內(nèi)容