什么是庫?
庫就是把一對.h .m 圖片資源 bundle 文件打包起來的一個文件养泡。
庫的分類
開源庫:源代碼是公開的柠座,主要體現(xiàn)在可以看到.m 文件的內(nèi)部實現(xiàn)。例如在 github 上大多數(shù)庫下載下來之后坑质,都可以看到 .h 和 .m 文件。
閉源庫:不公開源代碼临梗,一般只暴露 .h 文件涡扼。一般都是編譯過的二進(jìn)制代碼,看不到具體實現(xiàn)盟庞。
閉源庫又分:靜態(tài)庫 & 動態(tài)庫
靜態(tài)庫的存在形式:
.a
.framework
動態(tài)庫的存在形式
.dylib
.framework
靜態(tài)庫和動態(tài)庫的區(qū)別吃沪?
1. .a 一定是是靜態(tài)庫,dylib(dynamic library)一定是動態(tài)庫什猖。.framework 可能是靜態(tài)庫巷波,也有可能是動態(tài)庫萎津。
2. 靜態(tài)庫在鏈接時,會被完全賦值到可執(zhí)行文件中抹镊。如果多個 App 都使用了同一個靜態(tài)庫锉屈,那么每個 App 都會拷貝一份靜態(tài)庫,缺點(diǎn)是浪費(fèi)內(nèi)存垮耳。類似定義一個變量颈渊,使用該基本變量的時候,都是復(fù)制了一份便變量的值终佛。
3. 動態(tài)庫不會復(fù)制俊嗽,只有一份,程序運(yùn)行時動態(tài)加載到內(nèi)存中铃彰,系統(tǒng)最多只加載一次绍豁,多個程序公用一份,節(jié)約了內(nèi)存牙捉。類似于使用對象的引用竹揍。但是如果在 iOS 項目中使用了自定義動態(tài)庫,蘋果是不允許上架的邪铲。在 iOS 8 之后芬位,蘋果開放了動態(tài)加載 .dylib 的接口,用于掛載 .dylib 動態(tài)庫带到。
使用靜態(tài)庫時昧碉,會被完全復(fù)制到可執(zhí)行文件中,多次使用就多次復(fù)制揽惹。
動態(tài)庫鏈接時不復(fù)制被饿,程序運(yùn)行時由系統(tǒng)動態(tài)加載到內(nèi)存,供程序使用搪搏。
而且系統(tǒng)只會加載一次狭握,多個程序公用,節(jié)省內(nèi)存慕嚷。
靜態(tài)庫的運(yùn)用場景哥牍?
1. 保護(hù)公司的核心代碼毕泌,如訊飛語音搜索摸索了好多年得到的成果當(dāng)然要保存起來喝检,都公開了,公司如何生存撼泛?
2. 將 MRC 的項目打包成靜態(tài)庫挠说,可以在 ARC 模式下直接使用。免去了配置 .m 文件的 -fno-objc-arc
的配置愿题。
靜態(tài)庫的運(yùn)用場景损俭?
.a + .h
.h 可以看到頭文件蛙奖,也就是方法的聲明
.a & .framework 可以看作是所有的 .m 代碼加密后的一個二進(jìn)制文件。
.bundle
在使用第三方庫的時候杆兵,有時候會帶上 .bundle 文件雁仲。.bundle 實際上是一個物理文件夾,里面可以放圖片等資源琐脏。
因為 .bundle 是一個物理路徑文件夾攒砖,所以,里面放的資源文件不會和當(dāng)前的 target 項目的資源文件重名日裙。
.a 和 .framework
既然 .a 和 .framework 都可以完成靜態(tài)庫的封裝吹艇。
它們之后有和區(qū)別呢?
使用 .a 打包靜態(tài)庫時昂拂,包含了 .a 靜態(tài)庫 + .h 頭文件 + bundle 資源文件
使用 .framework 打包靜態(tài)庫時受神,所有的文件都包含在 .framework 包里了,比 .a 方便不少格侯。
所有的庫不管是.a .dylib .framework 最終目的鼻听,都是為了打包一堆
.h
,.m
,bundle
資源文件。并對外隱藏.m
的實現(xiàn)細(xì)節(jié)养交。
.a 靜態(tài)庫的制作步驟
第一步精算,創(chuàng)建一個 靜態(tài)庫項目
創(chuàng)建好的資源管理器
第二步,添加自己的 .h
, .m
文件碎连,并實現(xiàn)灰羽。
由于系統(tǒng)會默認(rèn)幫助我們添加一對
.h
.m
,所以我就不添加了鱼辙。直接用這對廉嚼。
第三步,在 .h
, .m
中定義方法的聲明 和 實現(xiàn)倒戏。
+ (void)classMethod;
- (void)instanceMethod;
+ (void)classMethod {
NSLog(@"我是來自 RelaxALib.a 靜態(tài)庫的類方法");
}
- (void)instanceMethod {
NSLog(@"我是來自 RelaxALib.a 靜態(tài)庫的實例方法");
}
第四步驟怠噪,設(shè)置編譯參數(shù)。
第五步杜跷,選擇模擬器 AND 真機(jī)設(shè)備傍念,分別 command + b 一次。完成 .a 庫的編譯葛闷。
第六步憋槐,右鍵 RelaxALib.a
-> show in finder
。
可以看到淑趾,有兩個文件夾阳仔。
兩個文件夾里,都有 libRelaxALib.a
這個文件扣泊。這個就是把 .m
文件實現(xiàn)編譯成的二進(jìn)制庫近范。
還有一個比較重要的文件夾 include
嘶摊,這里面放的是這個庫里的頭文件。
第七步 使用 lipo -create 模擬器 lib.a路徑 真機(jī) lib.a路徑 -ouput 存儲新的路徑/newLib.a
命令评矩。
為什么要用這個命令?
因為在編譯生成庫的時候叶堆,我們的選擇只能是單一的模擬器或者真機(jī)。
在模擬器下編譯的包只能跑在模擬下斥杜。
在真機(jī)下編譯的包只能跑在真機(jī)下蹂空。
使用 lipo -info lib.a路徑
查看包支持的架構(gòu)。
得到的結(jié)果是 : i386 和 x86_64 果录,分別是 32 位和 64 位操作系統(tǒng)的架構(gòu)上枕。
而在真機(jī)下 command + b 編譯的包支持的架構(gòu)則是 armv7 & armv7s & arm64。
armv7 是 iPhone 4s 的 CPU 架構(gòu)弱恒。
armv7s 是 iPhone5 & iPhone 5c 的 CPU 架構(gòu)辨萍。
arm64 則是 iPhone5s 以及以上的 CPU 架構(gòu)了。
所以返弹,可以通過 lipo -info xxx.a
的命令來查看庫支持的架構(gòu)锈玉。
第八步,將兩種架構(gòu)的包合并在一起,變成真機(jī)和模擬器都可以使用的包义起。
使用 lipo -create 真機(jī).a路徑 模擬器.a 路徑 -output 組合包.a 路徑
合并兩種框架后的新包拉背,放在桌面了。
可以使用 lipo -info
命令來查看此包支持的 CPU 架構(gòu)默终。
lipo -info newLib.a
第九步椅棺,使用我們剛編譯 + 合并 完成可以跑在真機(jī) & 模擬器上的 .a 包。
創(chuàng)建一個新的項目
然后使用包里定義好的功能即可齐蔽。
.framework 靜態(tài)庫制作
.a
是靜態(tài)庫 .dylib
是動態(tài)庫两疚。
.framework
是動態(tài)庫也可以是靜態(tài)庫。
為什么有 .a
靜態(tài)庫了含滴,還要出一個 .framework
靜態(tài)庫呢诱渤?
個人感覺,在使用層面上谈况。
.a
靜態(tài)庫的使用勺美,必須是.h(include 文件夾)
+.a 文件
+bundle
三個東西。
如果使用.framework
靜態(tài)庫的話碑韵,使用起來很方便赡茸。
這里主要說明 .framework
靜態(tài)庫的制作步驟。
第一步泼诱,創(chuàng)建一個 .framework項目
創(chuàng)建好之后的文件夾結(jié)構(gòu)
第二步:framework 的一些基本參數(shù)配置
第三步坛掠,創(chuàng)建自己的包文件赊锚。
第四步:配置哪些頭文件可以被使用包的項目導(dǎo)入
在 framework 本身里面治筒,如果沒有把 .h 頭文件添加到 pulbic 節(jié)點(diǎn)屉栓,而在 '庫名.h' 文件中導(dǎo)入這個頭文件。
在庫本身編譯的過程中耸袜,不會有任何問題友多。
但是在把庫給其他項目使用的時候,會報頭文件找不到的錯誤堤框?
那這個 private 的節(jié)點(diǎn)有什么作用嗎域滥?隱藏了頭文件,對庫自己也隱藏了蜈抓?
第五步启绰,在框架自己生成的 MyFirstFrame.h 文件里導(dǎo)入頭文件
#import <MyFirstFramework/PrivatePerson.h>
#import <MyFirstFramework/PublicPerson.h>
格式 :#import <框架名/文件.h>
第六步,分別選擇模擬器和設(shè)備沟使,進(jìn)行 command + b 編譯
第七步:將模擬器包和真機(jī)包合并
補(bǔ)充委可,合并的不是MyFirstFramework.framework
。
MyFirstFramework.framework
可以理解成一個文件夾腊嗡。
合并的是此文件夾里的 MyFramework
着倾。
第八步,把合并好的 MyFirstFramework替換到任意一個包里的 MyFirstFramework
什么意思?
我們可以看一下 MyFirstFramework.framework
這個文件里面的內(nèi)容燕少。
文件夾里卡者,本來就有 headers,info.plist,modules,MyFirstFramework。這4個元素客们。
它們在一起組成了一個完成的 MyFirstframework.framework
的包崇决。
我們現(xiàn)在用命令生成了一個新的 MyFirstFramework
文件。其他的文件對于一個完成的 MyFirstFramework.framework
包來說底挫,是比不可少的嗽桩,也是固定不變的。
我們要做的凄敢,就是把自己合并完畢后的 MyFirstFramework 替換一下就行了碌冶。
所以,隨便找一個之前的不管是真機(jī)還是模擬器的MyFristFramework.framework
包文件夾涝缝,替換里面的 MyFristFramework
包即可扑庞。
第九步,使用我們剛創(chuàng)建的 .framework 包
一些坑特別注意
對于 .framework 包封裝用命令的時候拒逮。
MyFristFramework.framework 是文件夾罐氨,只是的庫代碼二進(jìn)制文件是文件夾內(nèi)的 MyFristFramework二進(jìn)制文件。
lipo -create
&lipo -info
針對的是 MyFristFramework 文件 滩援,而不是 MyFristFramework.framework 文件夾