靜態(tài)庫和動(dòng)態(tài)庫
一杉适、靜態(tài)庫和動(dòng)態(tài)庫的存在形式
靜態(tài)庫: .a 和 .framework
動(dòng)態(tài)庫: .dylib 和 .framework
靜態(tài)庫和動(dòng)態(tài)庫在使用上的區(qū)別
靜態(tài)庫:鏈接時(shí),靜態(tài)庫會(huì)被完整地復(fù)制到可執(zhí)行文件中孵户, 被多次使用就有多份冗余拷貝 (左圖所示)
動(dòng)態(tài)庫:鏈接時(shí)不復(fù)制环揽,程序運(yùn)行時(shí)由系統(tǒng)動(dòng)態(tài)加載到內(nèi)存,供程序調(diào)用中姜,系統(tǒng)只加載一次消玄,多個(gè)程序共用,節(jié)省內(nèi)存丢胚。
需要注意的是:項(xiàng)目中如果使用了自制的動(dòng)態(tài)庫翩瓜,不能被上傳到 AppStore!
靜態(tài)庫和動(dòng)態(tài)庫中之所以都有.framework携龟,是因?yàn)樘O果自己的framework是動(dòng)態(tài)庫兔跌,以供我們開發(fā)者使用,但是峡蟋,我們自制時(shí)坟桅,制作的是.framework的靜態(tài)庫。
二蕊蝗、什么是.a仅乓、.bundle、.framework蓬戚?
在iOS中靜態(tài)庫以.a和.framework的形式存在夸楣,動(dòng)態(tài)庫以.dylib和.framework的形式存在。
之所以.framework既可能是動(dòng)態(tài)庫又可能是靜態(tài)庫子漩,是因?yàn)樘O果公司禁止用戶級App使用動(dòng)態(tài)庫豫喧,而自己卻又堂而皇之的使用動(dòng)態(tài)庫,這就造成了iOS中系統(tǒng)級的.framework是動(dòng)態(tài)庫幢泼,用戶級的.framework是靜態(tài)庫紧显。
二者區(qū)別不大,.a是純二進(jìn)制文件缕棵,.a文件不能單獨(dú)使用孵班,至少要有.h文件配合涉兽,而.framework除了二進(jìn)制文件外,還包含一些資源文件(頭文件重父,plist等)花椭,由于自身包含了頭文件忽匈,所以.framework可以單獨(dú)使用房午。
.a和.framework兩種靜態(tài)庫,通常都是把需要用的到圖片或者xib文件存放在一個(gè)bundle文件中丹允,而該bundle文件的名字和.a或.framework的名字相同郭厌。關(guān)于bundle文件的制作方法,后面第七大點(diǎn)介紹雕蔽。
三折柠、靜態(tài)庫使用的必要性
1>. 代碼的共享與重用
2>. 程序模塊化
3>. 分享給別人代碼庫時(shí)代碼隱藏
4>. 開發(fā)第三方SDK
四、編譯生成靜態(tài)庫時(shí)批狐,模式:debug和release的區(qū)別
靜態(tài)庫分為真機(jī)—Debug(調(diào)試)版本扇售、真機(jī)—Release(發(fā)布)版本、模擬器—Debug版本嚣艇、模擬器—Release版本承冰;開發(fā)中一般都打包Release(發(fā)布)版本,將真機(jī)和模擬器版本合并食零,提供外界困乒。
DEBUG,好處在于Xcode開啟很多服務(wù)來監(jiān)控錯(cuò)誤贰谣,讓程序員來調(diào)試用娜搂,但是耗性能。RELEASE吱抚,好處在于則相反百宇。
所以,建議:
——在生成靜態(tài)庫的時(shí)候秘豹,可以把上面Run的參數(shù)調(diào)整為Release携御,這樣節(jié)省內(nèi)存,運(yùn)行速度快憋肖。
——在平時(shí)用Run調(diào)試的時(shí)候因痛,在DEBUG下運(yùn)作正常后,在發(fā)布程序之前可修改Run的參數(shù)為Release岸更,再運(yùn)行一下模擬發(fā)布的情況鸵膏,因?yàn)橛袝r(shí)候在Debug下正常,在Release下會(huì)崩潰怎炊,兩者對錯(cuò)誤的敏感度不同谭企。
五廓译、制作.a靜態(tài)庫
創(chuàng)建工程:
在Build Settings -->link ->Other Linker Flags中(xcode 8.2)工程自動(dòng)添加了-ObjC。
在使用已經(jīng)制作的靜態(tài)庫的工程中债查,若是靜態(tài)庫中有分類非区,也需要加上-ObjC。
接著需要做:在copy files中添加所有的.h文件盹廷,這些.h都是暴露在外面的:
先注意檢查下面Release是否為NO:Yes表示只編譯選中模擬器設(shè)備對應(yīng)的架構(gòu)征绸,No則為編譯所有模擬器設(shè)備支持的cup架構(gòu)(Debug版本同理),選擇NO,然后分別在模擬器和真機(jī)下Command+B編譯一下俄占,會(huì)看到Products文件夾下的.a文件變?yōu)楹谏艿。@個(gè).a文件就是我們想要得到的靜態(tài)庫:
(親自測:release默認(rèn)為NO,debug默認(rèn)為YES。debug為YES情況下,在模擬器iphone6上編譯缸榄,得到的庫在7P上可以用渤弛,但是在5上就會(huì)崩潰,調(diào)整debug為NO,7和5都不崩潰)
合并模擬器的.a 和真機(jī)的.a(選Generic iOS Device 進(jìn)行編譯即可得到真機(jī)):
- 通過終端打開路徑/Users/**/Library/Developer/Xcode/DerivedData/甚带,選擇對應(yīng)的工程文件夾她肯,就是進(jìn)入制作靜態(tài)庫的工程。(在工程中的.a -- show in finder, 會(huì)看到Release-iphoneos和Release-iphonesimulator文件夾鹰贵,分別是真機(jī)和模擬器的.a文件)
- 合并真機(jī)和模擬器.a文件晴氨,在終端輸入以下命令行:lipo -create 模擬器.a文件的路徑 真機(jī).a文件的路徑 -output 合并后的保存路徑(例:lipo -create /Users/shelin/Library/Developer/Xcode/DerivedData/StaticLib/Build/Products/Release-iphoneos/libxxx.a /Users/shelin/Library/Developer/Xcode/DerivedData/StaticLib/Build/Products/Release-iphonesimulator/libxxx.a -output /Users/shelin/Desktop/StaticLib.a)最終會(huì)在桌面得到一個(gè)合并后的StaticLib.a文件,再將暴露出來的.h頭文件一起復(fù)制出來砾莱。
3.使用:只需將.a和暴露出來的.h頭文件導(dǎo)入工程目錄下就可供外界使用瑞筐。
制作的另外一種方式:
不用創(chuàng)建一個(gè)新的工程,在源代碼的項(xiàng)目里腊瑟,新建一個(gè)target:
在和項(xiàng)目并列地方有TestAProduct文件夾聚假,把需要編譯成.a的文件拖入這個(gè)文件夾里面,添加TestAProduct需要暴露的頭文件闰非,選擇TestAProduct目標(biāo)工程運(yùn)行膘格,則在Products里面會(huì)有生成的.a庫。(TestProduct的target里面的Compoile Sources需要有所有需要的.m的引用财松,不然運(yùn)行不會(huì)生成瘪贱,拖入之后,正常的target->TestPro也是可以運(yùn)行的辆毡,因?yàn)樗锩娴腃ompoile Sources有.m的引用)
六菜秦、制作.framework靜態(tài)庫
- 創(chuàng)建.framework的靜態(tài)和動(dòng)態(tài)庫都是:
靜態(tài)和動(dòng)態(tài)庫的選擇在于(linking-->Mach-o Type的選擇):
- 創(chuàng)建工程后,這里的Headres是自攜帶的:
(把.h文件都放到public里面舶掖,不然會(huì)報(bào)找不到的錯(cuò)誤)
編譯生成真機(jī)和模擬器的framework靜態(tài)庫的方法和.a的方法是一樣的球昨,接下來就是合成真機(jī)和模擬器的庫,這里和制作.a時(shí)的合并有點(diǎn)不同就是:
![Upload 0001.png failed. Please try again.]
這里合并用到的是里面的wgj_makeFramework:
![Upload 002.png failed. Please try again.]
例如:lipo -create /Users/wgj/Library/Developer/Xcode/DerivedData/wgj_makeFramework-gevmzbcgwfblmsewnayqsoutdztu/Build/Products/Debug-iphoneos/wgj_makeFramework.framework/wgj_makeFramework /Users/wgj/Library/Developer/Xcode/DerivedData/wgj_makeFramework-gevmzbcgwfblmsewnayqsoutdztu/Build/Products/Debug-iphonesimulator/wgj_makeFramework.framework/wgj_makeFramework -output /Users/wgj/Desktop/newFramework
其中眨攘,output后面的newFramework不是提前建好的文件夾主慰,生成之前嚣州,桌面上不需要做操作。
這樣共螺,生成后该肴,直接把桌面的生成的東東替換庫里面的最后層次的wgj_makeFramework就好了,newFramework名字最好改為wgj_makeFramework藐不。
七匀哄、制作.bundle
1、bundle資源庫的特點(diǎn)
Bundle是靜態(tài)的佳吞,也就是說拱雏,我們包含到包中的資源文件作為一個(gè)資源包是不參加項(xiàng)目編譯的。也就意味著底扳,bundle包中不能包含可執(zhí)行的文件。它僅僅是作為資源贡耽,被解析成為特定的2進(jìn)制數(shù)據(jù)
-
創(chuàng)建
01.png
3衷模、加入你需要編譯在bundle中的資源文件(若是圖片,需帶后綴.png)蒲赂。
當(dāng)然阱冶,默認(rèn)的配置也是可以的,如果你需要特定的優(yōu)化或者特定的路徑配置滥嘴,你可以進(jìn)行下面第4步的配置木蹬。
-
進(jìn)行可選設(shè)置
資源包只需要編譯不需要安裝:所以設(shè)置skip install 為YES;然后刪除安裝路徑如下:
02.png - 編譯即可得到.bundle文件
6.導(dǎo)入項(xiàng)目應(yīng)用,調(diào)用方式若皱,例如圖片的三種加載的方式:
//1.
// imageV.image = [UIImage imageNamed:@"wgj_bundle.bundle/Contents/Resources/0001.png"];
//2.
// NSString *fileS = [[NSBundle mainBundle] pathForResource:@"wgj_bundle.bundle/Contents/Resources/0001" ofType:@"png"];
// imageV.image = [UIImage imageWithContentsOfFile:fileS];
//3.
NSString *path = [[NSBundle mainBundle] pathForResource:@"wgj_bundle" ofType:@"bundle"];
NSBundle *bundle = [NSBundle bundleWithPath:path];
NSString *file = [bundle pathForResource:@"0001" ofType:@"png"];
imageV.image = [UIImage imageWithContentsOfFile:file];
注意:在制作靜態(tài)庫時(shí)镊叁,若把靜態(tài)庫里面的圖片(正常的圖片,不是bundle里面的)暴露出來走触,則靜態(tài)庫工程和用到靜態(tài)庫的工程可以直接用晦譬,[UIImage imageNamed:@"has.png"];如果是不暴露出來互广,則靜態(tài)庫工程和用到靜態(tài)庫的工程都用不了(靜態(tài)庫工程用了無效)敛腌。若是在制作靜態(tài)庫的時(shí)候,用.bundle文件封裝圖片資源惫皱,靜態(tài)庫制作時(shí)像樊,把.bundle文件暴露在外界,則也是一種方法,在外界通過路徑加載也是可以使用到圖片的(.bundle文件不暴露在外界旅敷,圖片在靜態(tài)庫中生棍,也是使用無效的)
(資源文件都打包放在這里。在制作Framework的時(shí)候不可以把圖片直接放在項(xiàng)目中扫皱,否則制作好之后圖片是一張一張的出現(xiàn)在項(xiàng)目中非常亂足绅,需要新建一個(gè)bundle將圖片放進(jìn)去捷绑,這里的bundle提供整個(gè)SDK的圖片資源。
注意:圖片放進(jìn)bundle之后不可以用[UIImage ImageWithName:]讀取圖片氢妈。要先找到bundle包再拿圖片)
八粹污、制作.framework動(dòng)態(tài)庫
制作.framework的動(dòng)態(tài)庫和制作.framework的靜態(tài)庫基本相同,其不同點(diǎn):
制作庫時(shí)這個(gè)地方改為:Dynamic Library,另外在使用已制作動(dòng)態(tài)庫的 工程中添加:
這個(gè)圖片中的Embedded Binaries 里面的庫是自制的動(dòng)態(tài)庫首量,需要手動(dòng)添加壮吩。
當(dāng)然在使用靜態(tài)庫時(shí),需要把這個(gè)Embedded Binaries 中的已手動(dòng)添加的動(dòng)態(tài)庫去掉加缘。(在導(dǎo)入自己制作的動(dòng)態(tài)庫時(shí)鸭叙,需要在Embedded Binaries中導(dǎo)入,不然會(huì)報(bào)錯(cuò):image not found拣宏。此時(shí)這個(gè)動(dòng)態(tài)庫會(huì)跟靜態(tài)庫一樣被拷貝到目標(biāo)程序中進(jìn)行編譯沈贝,蘋果又把這種Framework叫做Embedded Framework)