1. 靜態(tài)庫? ? Mach-O Type = Static Library
平時我們用的第三方SDK基本上都是靜態(tài)庫方篮,靜態(tài)庫的幾個特點:
在App項目編譯的時候會被拷貝一份編譯到目標程序中,相當(dāng)于將靜態(tài)庫嵌入了励负,所以得到的App二進制文件會變大藕溅。
在使用的時候,需要手動導(dǎo)入靜態(tài)庫所依賴的其他類庫继榆。(比如說某個SDK中使用到了CoreMotion.framework巾表,在使用的時候需要手動導(dǎo)入。有的SDK需要link十幾個系統(tǒng)庫略吨,這個時候非常惡心集币,只能一個一個手動加,這是靜態(tài)庫一個很大的不便之處翠忠。)
導(dǎo)入靜態(tài)庫的應(yīng)用可以減少對外界的依賴鞠苟,如果導(dǎo)入的是第三方動態(tài)庫,動態(tài)庫找不到的話應(yīng)用就會崩掉秽之,例如Linux上經(jīng)常出現(xiàn)的lib not found当娱。
靜態(tài)庫很大的一個優(yōu)點是減少耦合性,因為靜態(tài)庫中是不可以包含其他靜態(tài)庫的考榨,使用的時候要另外導(dǎo)入它的依賴庫趾访,最大限度的保證了每一個靜態(tài)庫都是獨立的,不會重復(fù)引用董虱。
2.? 動態(tài)庫? ? Mach-O Type = Dynamic Library
這個是我們最常用的一類庫扼鞋,使用頻率最高的UIKit.framework和Fundation.framework都屬于動態(tài)庫申鱼,所有.dylib和.tbd結(jié)尾的都屬于動態(tài)庫。動態(tài)庫的幾個特點:
平時使用的系統(tǒng)庫都放在iOS系統(tǒng)中云头,在你打包應(yīng)用程序的時候這些庫不會拷貝到你的程序中捐友,當(dāng)需要使用的時候會動態(tài)從iOS系統(tǒng)中加載它們,因為這個原因溃槐,動態(tài)庫也被稱作共享庫匣砖。編譯時才載入的特性,也可以讓我們隨時對庫進行替換昏滴,而不需要重新編譯代碼猴鲫。
這些庫是所有應(yīng)用公用的,換一種說法就是節(jié)省了應(yīng)用安裝包的體積谣殊,這是區(qū)別靜態(tài)庫很重要的一個特點拂共,因為靜態(tài)庫使用一次就要拷貝一次,非常浪費資源姻几。
使用動態(tài)庫的時候不需要再次link依賴庫宜狐,即導(dǎo)即用,這個就厲害了蛇捌。需要注意的是在導(dǎo)入第三方制作的動態(tài)庫時抚恒,需要在Embedded Binaries中導(dǎo)入,不然調(diào)用時會報錯:image not found络拌。此時這個動態(tài)庫會跟靜態(tài)庫一樣被拷貝到目標程序中進行編譯(會在App Bundle里生成一個Frameworks文件夾存放)俭驮,蘋果又把這種Framework叫做Embedded Framework,其中一個主要目的是為了App和App Extensions可以共用一份動態(tài)庫framework而不用分別鏈接一份庫的拷貝春贸。
關(guān)于Embedded Framework表鳍,如果將動態(tài)庫的工程文件直接引用進調(diào)用程序,如下圖這樣祥诽,則不用添加到Embedded里也能正常運行譬圣,不會報錯image not found,原因未知雄坪,猜測這樣組織XCode會將SubFramework做為靜態(tài)庫進行編譯
關(guān)于Embedded Framework,還有有一點要注意维哈,蘋果文檔說"If your containing app target links to an embedded framework, it must include the arm64 architecture or it will be rejected by the App Store."調(diào)試時只生成了模擬器指令集的動態(tài)framework绳姨,embedded之后運行程序肯能會有提示:This app could not be installed at this time導(dǎo)致無法運行,解決辦法就是需要同時生成包含模擬器和真機的指令集的動態(tài)庫
動態(tài)庫在制作的時候可以直接包含靜態(tài)庫(embed framework)阔挠,也能自動link所需要的依賴庫飘庄,將包含的庫直接鏈接進動態(tài)庫的二進制文件
由于IOS APP的沙盒機制,我們自己制作的庫购撼,不管是靜態(tài)庫還是動態(tài)庫跪削,都只能在沙盒中訪問谴仙,不同僅是靜態(tài)庫會被鏈接進App的可執(zhí)行文件內(nèi),而動態(tài)庫通過設(shè)置添加Embed Framework的方式在App沙盒中生成了一個Frameworks文件夾存放碾盐,因此比如沙盒里存在多個Excutable File(例如包含App Extension)共用這個framework晃跺,這時候可以用動態(tài)庫,共享一份Framework毫玖,其他大多數(shù)情況用靜態(tài)庫和動態(tài)庫區(qū)別就不大了
3.Umbrella Framework:包含子Framework的庫
如上所述掀虎,因為靜態(tài)庫中是不可以包含其他第三方庫的,而動態(tài)庫可以包含第三方庫付枫,所以Umbrella Framework一般都需要設(shè)置為動態(tài)庫烹玉,就可以包含子Framework了,網(wǎng)上有很多制作Umbrella Framework教程
4.因為蘋果不建議使用Umbrella Framework阐滩,實際使用也可能會產(chǎn)生一些問題二打,可以用單獨制作庫(靜態(tài)動態(tài)均可),使用時同時提供第三方依賴庫的方式實現(xiàn):
動態(tài)庫與靜態(tài)庫的制作流程基本一樣叶眉,包括頭文件的暴露等,唯一不同的是Mach-O Type的設(shè)置芹枷。本節(jié)將介紹Xcode制作Framework的過程衅疙,本次制作的Framework靜態(tài)庫依賴其他第三方靜態(tài)庫(Framework和.a)。
1>? 新建工程
新建Framework工程
這里要選Framework鸳慈,如果選擇右邊的Static Library制作出來的是.a靜態(tài)庫饱溢。
2>? 導(dǎo)入所有要打包的文件和其他第三方靜態(tài)庫
正常導(dǎo)入要打包的文件就可以了,在導(dǎo)入第三方靜態(tài)庫的時候要注意走芋,不要選擇添加到target中绩郎,如果添加進去要去target里面把第三方靜態(tài)庫刪掉(只需導(dǎo)入,不要添加進target)
導(dǎo)入第三方靜態(tài)庫
導(dǎo)入第三方靜態(tài)庫之后再link依賴的系統(tǒng)庫翁逞,像這樣
link依賴庫
注意上面的運行目標肋杖,因為我用的是Xcode8,最低支持到iOS8挖函。
要打包的文件和第三方靜態(tài)庫全部導(dǎo)入完成
所有文件導(dǎo)入情況
3>? 項目性質(zhì)修改
把項目的membership需改為public状植,否則頭文件暴露將會不正常
修改項目的membership
4>? 暴露頭文件
將頭文件暴露出去,供外界使用怨喘,所有的編譯文件都在Project中津畸,需要右擊添加到public里面
暴露頭文件
5>? ? 選擇Mach-O的編譯方式
這是最重要的一步,這一步?jīng)Q定我們制作出來的是靜態(tài)庫還是動態(tài)庫必怜,默認選擇的是Dynamic Library肉拓,要手動選擇Static Library
Mach-O 形式
6>? 編譯
如果你的依賴庫里面有l(wèi)ib開頭的dylib動態(tài)庫,此時應(yīng)該會報錯
動態(tài)庫鏈接報錯
什么意思呢梳庆?大概就是沒找到對應(yīng)的庫文件暖途,因為tbd是蘋果提供的新的動態(tài)庫格式卑惜,之前都是dylib,不知道這里又抽什么風(fēng)丧肴,下面解決問題残揉。
7>? tbd動態(tài)庫報錯修改
先把原來的.tbd刪掉,然后再次添加芋浮,這個時候選擇add other抱环,在彈出的窗口中按快捷鍵shift + command + G 調(diào)出finder的前往窗口,輸入/usr/lib纸巷,然后添加相應(yīng)的dylib動態(tài)庫
修改的動態(tài)庫
替換完成之后重新編譯項目镇草,生成Framework(可在Product文件中右擊在finder中顯示找到)
8>? 使用
新建一個文件夾,將制作好的靜態(tài)庫拷貝出來放進去瘤旨,再將第三方靜態(tài)庫拷貝到相同的文件夾中梯啤,此時只要將這個文件夾提供給外界使用就可以了,這是我寫的測試demo驗證打包好的SDK是否可以正常使用
制作完成使用
至此我們已經(jīng)完成了Framework中包含其他第三方靜態(tài)庫的制作存哲。
如果需要制作動態(tài)庫因宇,只需要在第5步中將Mach-O的形式改為Dynamic Library就可以了,其他步驟一樣
如果有問題請在留言區(qū)留言祟偷,或者郵件給我察滑,互相交流學(xué)習(xí)!