注:文章轉(zhuǎn)自他處铃将,原文地址:https://skyline75489.github.io/post/2015-8-14_ios_static_dynamic_framework_learning.htm
1.什么是庫闽晦?
庫(Library)說白了就是一段編譯好的二進制代碼,加上頭文件就可以供別人使用光酣。
還有,庫是共享程序代碼的方式,一般分為靜態(tài)庫和動態(tài)庫昂灵。
靜態(tài)庫:鏈接時完整地拷貝至可執(zhí)行文件中琉历,被多次使用就有多份冗余拷貝。
動態(tài)庫:鏈接時不復(fù)制见转,程序運行時由系統(tǒng)動態(tài)加載到內(nèi)存命雀,供程序調(diào)用,系統(tǒng)只加載一次斩箫,多個程序共用吏砂,節(jié)省內(nèi)存。
2.iOS里靜態(tài)庫形式
.a和.framework
3.iOS里動態(tài)庫形式乘客?
.dylib和.framework
4.framework為什么既是靜態(tài)庫又是動態(tài)庫狐血?
系統(tǒng)的.framework是動態(tài)庫,我們自己建立的.framework是靜態(tài)庫易核。
5.a與.framework有什么區(qū)別匈织?
.a是一個純二進制文件,.framework中除了有二進制文件之外還有資源文件牡直。
.a文件不能直接使用缀匕,至少要有.h文件配合,.framework文件可以直接使用碰逸。
.a+.h+sourceFile =.framework乡小。
建議用.framework.
6.什么場景下使用庫?
(1).某些代碼需要給別人使用花竞,但是我們不希望別人看到源碼劲件,就需要以庫的形式進行封裝,只暴露出頭文件约急。
(2).對于某些不會進行大的改動的代碼,我們想減少編譯的時間苗分,就可以把它打包成庫厌蔽,因為庫是已經(jīng)編譯好的二進制了,
編譯的時候只需要 Link 一下摔癣,不會浪費編譯時間奴饮。
上面提到的庫在使用的時候需要 Link纬向,Link 的方式有兩種,靜態(tài)和動態(tài)戴卜,于是便產(chǎn)生了靜態(tài)庫和動態(tài)庫逾条。
7.靜態(tài)庫
7.1靜態(tài)庫的介紹
靜態(tài)庫即靜態(tài)鏈接庫(Windows 下的 .lib,Linux 和 Mac 下的 .a)投剥。之所以叫做靜態(tài)师脂,是因為靜態(tài)庫在編譯的時候會被直接拷貝一份,復(fù)制到目標(biāo)程序里江锨,這段代碼在目標(biāo)程序里就不會再改變了吃警。
靜態(tài)庫的好處很明顯,編譯完成之后啄育,庫文件實際上就沒有作用了酌心。目標(biāo)程序沒有外部依賴,直接就可以運行挑豌。當(dāng)然其缺點也很明顯安券,就是會使用目標(biāo)程序的體積增大。
7.2為什么要使用靜態(tài)庫氓英?
方便共享代碼侯勉,便于合理使用。
實現(xiàn)iOS程序的模塊化债蓝】呛祝可以把固定的業(yè)務(wù)模塊化成靜態(tài)庫。
和別人分享你的代碼庫饰迹,但不想讓別人看到你代碼的實現(xiàn)芳誓。
開發(fā)第三方sdk的需要。
7.3制作靜態(tài)庫時的幾點注意
1 注意理解:無論是.a靜態(tài)庫還.framework靜態(tài)庫啊鸭,我們需要的都是二進制文件+.h+其它資源文件的形式锹淌,不同的是,.a本身就是二進制文件赠制,需要我們自己配上.h和其它文件才能使用赂摆,而.framework本身已經(jīng)包含了.h和其它文件,可以直接使用钟些。
2 圖片資源的處理:兩種靜態(tài)庫烟号,一般都是把圖片文件單獨的放在一個.bundle文件中,一般.bundle的名字和.a或.framework的名字相同政恍。.bundle文件很好弄汪拥,新建一個文件夾,把它改名為.bundle就可以了篙耗,右鍵迫筑,顯示包內(nèi)容可以向其中添加圖片資源宪赶。
3 category是我們實際開發(fā)項目中經(jīng)常用到的,把category打成靜態(tài)庫是沒有問題的脯燃,但是在用這個靜態(tài)庫的工程中搂妻,調(diào)用category中的方法時會有找不到該方法的運行時錯誤(selector not recognized),解決辦法是:在使用靜態(tài)庫的工程中配置other linker flags的值為-ObjC辕棚。
4 如果一個靜態(tài)庫很復(fù)雜欲主,需要暴露的.h比較多的話,就可以在靜態(tài)庫的內(nèi)部創(chuàng)建一個.h文件(一般這個.h文件的名字和靜態(tài)庫的名字相同)坟募,然后把所有需要暴露出來的.h文件都集中放在這個.h文件中岛蚤,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出來就可以了懈糯。
5.注意:動態(tài)庫可以使用但是不能上架涤妒!
而且使用的時候必須在添加動態(tài)庫的工程中的 General-->Embedded Binaries 中添加一下,具體如圖所示:
那么如何想使用動態(tài)庫上架呢赚哗?我們只需要在制作的時候?qū)⑵渚幾g成靜態(tài)庫她紫。在Buid Settins-->Mach-O Type--> Static Library具體如圖:
同樣不要忘了編譯,這樣編譯出來的庫就是靜態(tài)庫了屿储。我們就可以像靜態(tài)庫一樣在工程中使用了贿讹。
8.動態(tài)庫
8.1 什么是動態(tài)庫
動態(tài)庫即動態(tài)鏈接庫(Windows 下的 .dll,Linux 下的 .so够掠,Mac 下的 .dylib/.tbd)民褂。與靜態(tài)庫相反,動態(tài)庫在編譯時并不會被拷貝到目標(biāo)程序中疯潭,目標(biāo)程序中只會存儲指向動態(tài)庫的引用赊堪。等到程序運行時,動態(tài)庫才會被真正加載進來竖哩。
8.2動態(tài)庫的優(yōu)缺點
不需要拷貝到目標(biāo)程序中哭廉,不會影響目標(biāo)程序的體積,而且同一份庫可以被多個程序使用(因為這個原因相叁,動態(tài)庫也被稱作共享庫)遵绰。同時,編譯時才載入的特性增淹,也可以讓我們隨時對庫進行替換椿访,而不需要重新編譯代碼。動態(tài)庫帶來的問題主要是虑润,動態(tài)載入會帶來一部分性能損失赎离,使用動態(tài)庫也會使得程序依賴于外部環(huán)境。如果環(huán)境缺少動態(tài)庫或者庫的版本不正確端辱,就會導(dǎo)致程序無法運行(Linux 下喜聞樂見的 lib not found 錯誤)梁剔。
9.iOS Framework
9.1什么是framework
除了上面提到的 .a 和 .dylib/.tbd 之外,Mac OS/iOS 平臺還可以使用 Framework舞蔽。
Framework :實際上是一種打包方式荣病,將庫的二進制文件,頭文件和有關(guān)的資源文件打包到一起渗柿,方便管理和分發(fā)个盆。
framework是Cocoa/Cocoa Touch程序中使用的一種資源打包方式,可以將將代碼文件朵栖、頭文件颊亮、資源文件、說明文檔等集中在一起陨溅,方便開發(fā)者使用终惑。
Cocoa/Cocoa Touch開發(fā)框架本身提供了大量的Framework,比如Foundation.framework/UIKit.framework/AppKit.framework等门扇。需要注意的是雹有,這些framework無一例外都是動態(tài)庫。
平時我們用的第三方SDK的framework都是靜態(tài)庫臼寄,真正的動態(tài)庫是上不了AppStore的霸奕。
9.2framework為什么既是靜態(tài)庫又是動態(tài)庫?
系統(tǒng)的.framework是動態(tài)庫吉拳,我們自己建立的.framework是靜態(tài)庫质帅。
9.3framework背景介紹
(1).在 iOS 8 之前,iOS 平臺不支持使用動態(tài) Framework留攒,開發(fā)者可以使用的 Framework 只有蘋果自家的 UIKit.Framework煤惩,F(xiàn)oundation.Framework 等。
?(2) ?.iOS 8/Xcode 6 推出之后稼跳,iOS 平臺添加了動態(tài)庫的支持盟庞,同時 Xcode 6 也原生自帶了 Framework 支持(動態(tài)和靜態(tài)都可以)。
為什么 iOS 8 要添加動態(tài)庫的支持汤善?唯一的理由大概就是 Extension 的出現(xiàn)什猖。Extension 和 App 是兩個分開的可執(zhí)行文件,同時需要共享代碼红淡,這種情況下動態(tài)庫的支持就是必不可少的了不狮。但是這種動態(tài) Framework 和系統(tǒng)的 UIKit.Framework 還是有很大區(qū)別。系統(tǒng)的 Framework 不需要拷貝到目標(biāo)程序中在旱,我們自己做出來的 Framework 哪怕是動態(tài)的摇零,最后也還是要拷貝到 App 中(App 和 Extension 的 Bundle 是共享的),因此蘋果又把這種 Framework 稱為Embedded Framework桶蝎。
10. CocoaPods 的做法
在純 ObjC 的項目中驻仅,CocoaPods 使用編譯靜態(tài)庫 .a 方法將代碼集成到項目中谅畅。在 Pods 項目中的每個 target 都對應(yīng)這一個 Pod 的靜態(tài)庫。不過在編譯過程中并不會真的產(chǎn)出 .a 文件噪服。如果需要 .a 文件的話毡泻,可以參考這里,或者使用CocoasPods-Packager這個插件粘优。
當(dāng)不想發(fā)布代碼的時候仇味,也可以使用 Framework 發(fā)布 Pod,CocoaPods 提供了vendored_framework
選項來使用第三方 Framework雹顺,具體的做法可以參考這里1和這里2丹墨。
對于 Swift 項目,CocoaPods 提供了動態(tài) Framework 的支持嬉愧,通過 use_frameworks!
[更多參考資料]
WWDC2014之iOS使用動態(tài)庫中有很詳細(xì)的創(chuàng)建動態(tài)庫和使用動態(tài)庫的教程贩挣。
博客:http://geeklu.com/2014/02/objc-lib/
https://stackoverflow.com/questions/2649334/difference-between-static-and-shared-libraries
https://stackoverflow.com/questions/25080914/will-ios-8-support-dynamic-linking