iOS動(dòng)態(tài)庫,靜態(tài)庫以及framework

注:文章轉(zhuǎn)自他處,原文地址:https://skyline75489.github.io/post/2015-8-14_ios_static_dynamic_framework_learning.htm

1.什么是庫?

庫(Library)說白了就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別人使用。

還有,庫是共享程序代碼的方式,一般分為靜態(tài)庫和動(dòng)態(tài)庫。

靜態(tài)庫:鏈接時(shí)完整地拷貝至可執(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)存。


2.iOS里靜態(tài)庫形式

.a和.framework

3.iOS里動(dòng)態(tài)庫形式?

.dylib和.framework


4.framework為什么既是靜態(tài)庫又是動(dòng)態(tài)庫?

系統(tǒng)的.framework是動(dòng)態(tài)庫,我們自己建立的.framework是靜態(tài)庫。

5.a與.framework有什么區(qū)別?

.a是一個(gè)純二進(jìn)制文件,.framework中除了有二進(jìn)制文件之外還有資源文件。

.a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。

.a+.h+sourceFile =.framework。

建議用.framework.


6.什么場景下使用庫?

(1).某些代碼需要給別人使用,但是我們不希望別人看到源碼,就需要以庫的形式進(jìn)行封裝,只暴露出頭文件。

(2).對于某些不會進(jìn)行大的改動(dòng)的代碼,我們想減少編譯的時(shí)間,就可以把它打包成庫,因?yàn)閹焓且呀?jīng)編譯好的二進(jìn)制了,

編譯的時(shí)候只需要 Link 一下,不會浪費(fèi)編譯時(shí)間。

上面提到的庫在使用的時(shí)候需要 Link,Link 的方式有兩種,靜態(tài)和動(dòng)態(tài),于是便產(chǎn)生了靜態(tài)庫和動(dòng)態(tài)庫。


7.靜態(tài)庫

7.1靜態(tài)庫的介紹

靜態(tài)庫即靜態(tài)鏈接庫(Windows 下的 .lib,Linux 和 Mac 下的 .a)。之所以叫做靜態(tài),是因?yàn)殪o態(tài)庫在編譯的時(shí)候會被直接拷貝一份,復(fù)制到目標(biāo)程序里,這段代碼在目標(biāo)程序里就不會再改變了。

靜態(tài)庫的好處很明顯,編譯完成之后,庫文件實(shí)際上就沒有作用了。目標(biāo)程序沒有外部依賴,直接就可以運(yùn)行。當(dāng)然其缺點(diǎn)也很明顯,就是會使用目標(biāo)程序的體積增大。

7.2為什么要使用靜態(tài)庫?

方便共享代碼,便于合理使用。

實(shí)現(xiàn)iOS程序的模塊化。可以把固定的業(yè)務(wù)模塊化成靜態(tài)庫。

和別人分享你的代碼庫,但不想讓別人看到你代碼的實(shí)現(xiàn)。

開發(fā)第三方sdk的需要。

7.3制作靜態(tài)庫時(shí)的幾點(diǎn)注意

1 注意理解:無論是.a靜態(tài)庫還.framework靜態(tài)庫,我們需要的都是二進(jìn)制文件+.h+其它資源文件的形式,不同的是,.a本身就是二進(jìn)制文件,需要我們自己配上.h和其它文件才能使用,而.framework本身已經(jīng)包含了.h和其它文件,可以直接使用。

2 圖片資源的處理:兩種靜態(tài)庫,一般都是把圖片文件單獨(dú)的放在一個(gè).bundle文件中,一般.bundle的名字和.a或.framework的名字相同。.bundle文件很好弄,新建一個(gè)文件夾,把它改名為.bundle就可以了,右鍵,顯示包內(nèi)容可以向其中添加圖片資源。

3 category是我們實(shí)際開發(fā)項(xiàng)目中經(jīng)常用到的,把category打成靜態(tài)庫是沒有問題的,但是在用這個(gè)靜態(tài)庫的工程中,調(diào)用category中的方法時(shí)會有找不到該方法的運(yùn)行時(shí)錯(cuò)誤(selector not recognized),解決辦法是:在使用靜態(tài)庫的工程中配置other linker flags的值為-ObjC。

4 如果一個(gè)靜態(tài)庫很復(fù)雜,需要暴露的.h比較多的話,就可以在靜態(tài)庫的內(nèi)部創(chuàng)建一個(gè).h文件(一般這個(gè).h文件的名字和靜態(tài)庫的名字相同),然后把所有需要暴露出來的.h文件都集中放在這個(gè).h文件中,而那些原本需要暴露的.h都不需要再暴露了,只需要把.h暴露出來就可以了。

5.注意:動(dòng)態(tài)庫可以使用但是不能上架!

而且使用的時(shí)候必須在添加動(dòng)態(tài)庫的工程中的 General-->Embedded Binaries 中添加一下,具體如圖所示:


那么如何想使用動(dòng)態(tài)庫上架呢?我們只需要在制作的時(shí)候?qū)⑵渚幾g成靜態(tài)庫。在Buid Settins-->Mach-O Type--> Static Library具體如圖:


動(dòng)態(tài)轉(zhuǎn)靜態(tài)

同樣不要忘了編譯,這樣編譯出來的庫就是靜態(tài)庫了。我們就可以像靜態(tài)庫一樣在工程中使用了。


8.動(dòng)態(tài)庫

8.1 什么是動(dòng)態(tài)庫

動(dòng)態(tài)庫即動(dòng)態(tài)鏈接庫(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib/.tbd)。與靜態(tài)庫相反,動(dòng)態(tài)庫在編譯時(shí)并不會被拷貝到目標(biāo)程序中,目標(biāo)程序中只會存儲指向動(dòng)態(tài)庫的引用。等到程序運(yùn)行時(shí),動(dòng)態(tài)庫才會被真正加載進(jìn)來。

8.2動(dòng)態(tài)庫的優(yōu)缺點(diǎn)

不需要拷貝到目標(biāo)程序中,不會影響目標(biāo)程序的體積,而且同一份庫可以被多個(gè)程序使用(因?yàn)檫@個(gè)原因,動(dòng)態(tài)庫也被稱作共享庫)。同時(shí),編譯時(shí)才載入的特性,也可以讓我們隨時(shí)對庫進(jìn)行替換,而不需要重新編譯代碼。動(dòng)態(tài)庫帶來的問題主要是,動(dòng)態(tài)載入會帶來一部分性能損失,使用動(dòng)態(tài)庫也會使得程序依賴于外部環(huán)境。如果環(huán)境缺少動(dòng)態(tài)庫或者庫的版本不正確,就會導(dǎo)致程序無法運(yùn)行(Linux 下喜聞樂見的 lib not found 錯(cuò)誤)。


9.iOS Framework

9.1什么是framework

除了上面提到的 .a 和 .dylib/.tbd 之外,Mac OS/iOS 平臺還可以使用 Framework。

Framework :實(shí)際上是一種打包方式,將庫的二進(jìn)制文件,頭文件和有關(guān)的資源文件打包到一起,方便管理和分發(fā)。

framework是Cocoa/Cocoa Touch程序中使用的一種資源打包方式,可以將將代碼文件、頭文件、資源文件、說明文檔等集中在一起,方便開發(fā)者使用。

Cocoa/Cocoa Touch開發(fā)框架本身提供了大量的Framework,比如Foundation.framework/UIKit.framework/AppKit.framework等。需要注意的是,這些framework無一例外都是動(dòng)態(tài)庫。

平時(shí)我們用的第三方SDK的framework都是靜態(tài)庫,真正的動(dòng)態(tài)庫是上不了AppStore的。

9.2framework為什么既是靜態(tài)庫又是動(dòng)態(tài)庫?

系統(tǒng)的.framework是動(dòng)態(tài)庫,我們自己建立的.framework是靜態(tài)庫。

9.3framework背景介紹

(1).在 iOS 8 之前,iOS 平臺不支持使用動(dòng)態(tài) Framework,開發(fā)者可以使用的 Framework 只有蘋果自家的 UIKit.Framework,F(xiàn)oundation.Framework 等。

?(2) ?.iOS 8/Xcode 6 推出之后,iOS 平臺添加了動(dòng)態(tài)庫的支持,同時(shí) Xcode 6 也原生自帶了 Framework 支持(動(dòng)態(tài)和靜態(tài)都可以)。

為什么 iOS 8 要添加動(dòng)態(tài)庫的支持?唯一的理由大概就是 Extension 的出現(xiàn)。Extension 和 App 是兩個(gè)分開的可執(zhí)行文件,同時(shí)需要共享代碼,這種情況下動(dòng)態(tài)庫的支持就是必不可少的了。但是這種動(dòng)態(tài) Framework 和系統(tǒng)的 UIKit.Framework 還是有很大區(qū)別。系統(tǒng)的 Framework 不需要拷貝到目標(biāo)程序中,我們自己做出來的 Framework 哪怕是動(dòng)態(tài)的,最后也還是要拷貝到 App 中(App 和 Extension 的 Bundle 是共享的),因此蘋果又把這種 Framework 稱為Embedded Framework。


10. CocoaPods 的做法

在純 ObjC 的項(xiàng)目中,CocoaPods 使用編譯靜態(tài)庫 .a 方法將代碼集成到項(xiàng)目中。在 Pods 項(xiàng)目中的每個(gè) target 都對應(yīng)這一個(gè) Pod 的靜態(tài)庫。不過在編譯過程中并不會真的產(chǎn)出 .a 文件。如果需要 .a 文件的話,可以參考這里,或者使用CocoasPods-Packager這個(gè)插件。

當(dāng)不想發(fā)布代碼的時(shí)候,也可以使用 Framework 發(fā)布 Pod,CocoaPods 提供了vendored_framework

選項(xiàng)來使用第三方 Framework,具體的做法可以參考這里1這里2

對于 Swift 項(xiàng)目,CocoaPods 提供了動(dòng)態(tài) Framework 的支持,通過 use_frameworks!


[更多參考資料]

WWDC2014之iOS使用動(dòng)態(tài)庫中有很詳細(xì)的創(chuàng)建動(dòng)態(tài)庫和使用動(dòng)態(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

https://stackoverflow.com/questions/6245761/difference-between-framework-and-static-library-in-xcode4-and-how-to-call-them http://blog.cocoapods.org/CocoaPods-0.36/ 文/千_城(簡書作者) 原文鏈接:http://www.itdecent.cn/p/02b7032344d7

IOSOpenDev越獄開發(fā)環(huán)境配置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容