IOS 打包靜態(tài)庫詳細(xì)介紹
IOS 打包靜態(tài)庫詳細(xì)介紹
一、前言
前段時間看的一本書上說:“隔著一段距離看,很多有趣的知識看起來都很唬人。”比如說這篇我要總結(jié)的“靜態(tài)庫知識”,在我初出茅廬的時候著實覺得那些后綴名為“.frameworke”、“.a”、“.dylib”的文件很神秘,很高冷。那時我雖然知道只要導(dǎo)入一個庫就能引用庫里面很多封裝好的東西,但對這個“庫”究竟是什么“鬼”,一直都是云里霧里。好了廢話不多說,看下去就知道它是個什么“鬼”。
二 、一些概念的補充
1、 什么是庫?
所謂庫就是程序代碼的集合,是共享程序代碼的一種方式。
2、 庫的分類
根據(jù)程序代碼的開源情況,庫可以分為兩類
開源庫
源代碼是公開的,你可以看到具體實現(xiàn)。比如GitHub上比較出名的第三方框架AFNetworking、SDWebImage。
閉源庫
不公開源代碼,只公開調(diào)用的接口,看不到具體的實現(xiàn),是一個編譯后的二進制文件。這種常見于一些公司的SDK包,比如高德地圖SDK、環(huán)信即時通訊SDK等等。而閉源庫又分為兩類:靜態(tài)庫和動態(tài)庫。本篇重點要講的便是其中的靜態(tài)庫。
3、靜態(tài)庫和動態(tài)庫的存在形式和使用區(qū)別
存在形式:
靜態(tài)庫
以".a"或者“.framework”為文件后綴名
動態(tài)庫
以".dylib"或者“.framework”為文件后綴名
使用區(qū)別:
靜態(tài)庫鏈接時會被完整的復(fù)制到可執(zhí)行文件中,被多次使用就有多份拷貝。
靜態(tài)庫被程序使用時
動態(tài)庫鏈接時不復(fù)制,程序運行時由系統(tǒng)動態(tài)加載到內(nèi)存,供程序調(diào)用。而且系統(tǒng)只加載一次,多個程序共用,節(jié)省內(nèi)存。
動態(tài)庫被程序使用時
4、iOS 設(shè)備的CPU架構(gòu)
模擬器:
4s-5: i386
5s-7 Plus: x86_64
真機(iOS設(shè)備):
armv6: iPhone、iPhone 2、iPhone 3G、iPod Touch(第一代)、iPod Touch(第二代)
armv7: iPhone 3Gs、iPhone 4、iPhone 4s、iPad、iPad 2
armv7s: iPhone 5、iPhone 5c (靜態(tài)庫只要支持了armv7,就可以在armv7s的架構(gòu)上運行)
arm64: iPhone 5s、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPad Air、iPad Air2、iPad mini2、iPad mini3
注:真機iPhone7、iPhone7 Plus A10處理器到底是什么架構(gòu)暫時不得而知,沒查到相關(guān)資料,貌似還沒公布,但是模擬器是x86_64。
三、打包靜態(tài)庫
因為靜態(tài)庫存在兩種形式,我們先看.a靜態(tài)庫的打包
.a文件靜態(tài)庫打包
1、打開Xcode創(chuàng)建一個新的工程,這里以Xcode8為例,選擇工程如下:
創(chuàng)建一個新的工程
2、創(chuàng)建工程完畢后,再創(chuàng)建一個工具類StaticLibTool,添加一個方法用于測試
創(chuàng)建一個工具類,添加測試方法
StaticLibTool.m文件實現(xiàn)如下
taticLibTool.m文件實現(xiàn)
3、運行工程進行打包
運行工程打包
運行完畢后,我們會看到工程中Products文件夾下的libStaticLib.a文件由紅色變成了黑色。右鍵show in finder可以在其目錄下找到它。這就是我們打包好的.a靜態(tài)文件了。
打包好的.a靜態(tài)文件
但是這樣就完了嗎?當(dāng)然沒有,我們知道靜態(tài)庫存在的最大意義是隱藏代碼的具體實現(xiàn),但是這也隱藏的太徹底了,總要公開些接口或者頭文件供人調(diào)用吧。
4、公開接口頭文件
targets->Build Phases->Copy Files->"+"你需要公開的頭文件
這里我們把新建的測試類StaticLibTool.h公開
公開接口頭文件
公開頭文件后,我們再按上述1、2、3流程重新運行打包,我們會得到一個頭文件和一個.a靜態(tài)庫(如下圖),而這正是我們所需要的。
重新運行打包
5、新建一個可運行的工程,把這兩個打包好的文件拖入項目測試
測試
選擇Iphone7模擬器運行,程序正常運行,點擊模擬器屏幕,打印日志如下:
日志輸出
我們可以看到輸出沒有問題,打包.a靜態(tài)庫大功告成。
但是,別高興的太早。當(dāng)我把模擬器切換成Iphone5運行時,編譯直接不通過,報錯如下:
iPhone 5模擬器運行時的編譯錯誤
上圖“Undefined symbols for architecture i386”是什么意思呢?意思是我們的libStaticLib.a靜態(tài)庫不支持i386架構(gòu)。那i386又是什么鬼?不清楚的可以拉上去看“iOS 設(shè)備的CPU架構(gòu)”,這里就不多做解釋了。
iPhone 5模擬器正好是i386架構(gòu),而我們打包的靜態(tài)庫不支持。但是iPhone 7模擬器運行卻沒有問題,這說明我們打包的靜態(tài)庫正好支持iPhone 7模擬器 的cpu架構(gòu) x86_64。如何查看靜態(tài)庫所支持的架構(gòu),請看下一步。
6、終端查看靜態(tài)庫所支持的架構(gòu)
終端->cd進入庫文件路徑->lipo -info 庫名
終端查看靜態(tài)庫所支持的架構(gòu)
上圖可以看到,我們的靜態(tài)庫僅支持x86_64架構(gòu),也就是說此靜態(tài)庫只可運行在iphone5s-iphone7plus之間的模擬器設(shè)備。所以剛才我們運行iphone5模擬器時,編譯會報錯。
到這里就可以進一步解釋下,打包靜態(tài)庫時,你用什么模擬器運行,打包出來的靜態(tài)庫就支持什么模擬器的架構(gòu),而剛才我打包時是用iPhone7運行,所以僅支持架構(gòu)x86_64。那么這就太麻煩了,可以打包一個靜態(tài)庫支持多種架構(gòu)的模擬器嗎?答案是肯定的,請看下一步。
7、設(shè)置適配所有模擬器架構(gòu)
project -> buildSeting -> Build Active Architecture Only 設(shè)為NO
設(shè)置適配所有模擬器架構(gòu)
設(shè)置完成后,我們重新運行打包靜態(tài)庫文件(這時你可隨便選一個模擬器),按照上述第6步終端查看其支持的架構(gòu),我們可以看到終端輸出的結(jié)果是同時支持 i386和x86_64,這也就意味著同時支持所有模擬器。
到這里打包.a靜態(tài)庫已經(jīng)告一段落,但是按上述流程打包的只能在模擬器上跑,真機是不能運行的,因為ios真機設(shè)備跟模擬器的架構(gòu)又不一樣(怎么不一樣自己拉上去看),所以還沒完(我也不想啊 ),請看下一步
8、打包支持真機架構(gòu)的靜態(tài)庫
所有流程都跟上面的一樣,只是我們運行打包時要選擇真機運行,如下圖你可以選擇自己插上去的真機,也可以選擇Generic ios Devices。當(dāng)然不要忘記了設(shè)置支持所有真機機型架構(gòu): Build Active Architecture Only 設(shè)為NO。
打包支持真機架構(gòu)的靜態(tài)庫
我們可以看下打包出來的終端查看結(jié)果如下:
終端輸出結(jié)果
上圖可以看到同時支持armv7和arm64,也就是支持所有ios設(shè)備。好了到此打包.a靜態(tài)庫算是告一段落。
.frameworke文件靜態(tài)庫打包
1、依然Xcode創(chuàng)建一個新的工程FrameworkeLib,選擇工程如下:
創(chuàng)建一個新的工程
創(chuàng)建完成后我們可以看到,工程本身自帶一個FrameworkeLib.h文件,這是類似一個主頭文件一樣的東西
FrameworkeLib.h文件
2、創(chuàng)建需要測試的類,為了方便我把上述打包.a的測試類StaticLibTool直接拖來使用。
3、設(shè)置支持所有模擬器架構(gòu)或真機架構(gòu)(和打包.a第7步驟一樣)
4、公開頭文件
target-Build Phases - Headers -把需要公開的頭文件從project拖入Public
暴露頭文件
5、設(shè)置打包的是靜態(tài)庫。因為動態(tài)庫也可以是以framework形式存在,所以需要設(shè)置,否則默認(rèn)打出來的是動態(tài)庫
target->BuildSetting ->搜索關(guān)鍵字mach->Mach-o Type 設(shè)為Static Library(這個默認(rèn)選項是動態(tài)的)
設(shè)置打包的是靜態(tài)庫
6、選中真機或模擬器運行設(shè)備打包(與打包.a一樣),完成后Products文件夾下的FrameworkeLib.framework文件由紅色變成了黑色,右鍵show in finder 顯示如下:
打包結(jié)果
FrameworkeLib.framework拖入項目便可直接使用,這里就不再進行測試了。此外還要補充的一點是,打包靜態(tài)庫的時候還需注意打包的是測試版(Debug)還是發(fā)布版(Release),這個根據(jù)你自己的需求決定,而如何進行設(shè)置請下一步驟。
7、設(shè)置打包靜態(tài)庫的測試版和發(fā)布版(.a和.frameworke)
product -> scheme -> Edit scheme -> Run->選擇Debug或Release
設(shè)置版本
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
iOS開發(fā)之用javascript調(diào)用oc方法而非url
本文說的是非攔截URL進行判斷,然后調(diào)用oc方法這種調(diào)用手段,所以不用討論說為什么不用url這種方法,具體看需求,有需要的可以參考。2016-07-07一個iOS上的秒表小應(yīng)用的實現(xiàn)方法分享
這篇文章主要介紹了一個iOS上的秒表小應(yīng)用的實現(xiàn)方法分享,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-10-10iOS應(yīng)用設(shè)計模式開發(fā)中職責(zé)鏈(責(zé)任鏈)模式的實現(xiàn)解析
這篇文章主要介紹了iOS應(yīng)用設(shè)計模式開發(fā)中職責(zé)鏈模式的相關(guān)實現(xiàn)解析,示例代碼為傳統(tǒng)的Objective-C,需要的朋友可以參考下2016-03-03iOS常用算法之兩個有序數(shù)組合并(要求時間復(fù)雜度為0(n))
這篇文章主要介紹了iOS常用算法之兩個有序數(shù)組合并(要求時間復(fù)雜度為0(n)),實現(xiàn)思路是先將一個數(shù)組作為合并后的數(shù)組, 然后遍歷第二個數(shù)組的每項元素,需要的朋友可以參考下2019-07-07iOS 隱藏導(dǎo)航條和狀態(tài)欄實現(xiàn)方法
這篇文章主要介紹了 iOS隱藏導(dǎo)航條和狀態(tài)欄實現(xiàn)方法的相關(guān)資料,有時候根據(jù)需求開發(fā)APP 需要隱藏導(dǎo)航欄和狀態(tài)欄,這里提供了實現(xiàn)方法需要的朋友可以參考下2016-11-11