首先來看什麼是庫,庫(Library)說白了就是一段編譯好的二進制代碼,加上頭文件就能夠供別人使用。html
何時咱們會用到庫呢?一種狀況是某些代碼須要給別人使用,可是咱們不但願別人看到源碼,就須要以庫的形式進行封裝,只暴露出頭文件。另一種狀況是,對於某些不會進行大的改動的代碼,咱們想減小編譯的時間,就能夠把它打包成庫,由於庫是已經編譯好的二進制了,編譯的時候只須要 Link 一下,不會浪費編譯時間。ios
上面提到庫在使用的時候須要 Link,Link 的方式有兩種,靜態和動態,因而便產生了靜態庫和動態庫。git
靜態庫即靜態連接庫(Windows 下的 .lib,Linux 和 Mac 下的 .a)。之因此叫作靜態,是由於靜態庫在編譯的時候會被直接拷貝一份,複製到目標程序裏,這段代碼在目標程序裏就不會再改變了。github
靜態庫的好處很明顯,編譯完成以後,庫文件實際上就沒有做用了。目標程序沒有外部依賴,直接就能夠運行。固然其缺點也很明顯,就是會使用目標程序的體積增大。swift
動態庫即動態連接庫(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib)。與靜態庫相反,動態庫在編譯時並不會被拷貝到目標程序中,目標程序中只會存儲指向動態庫的引用。等到程序運行時,動態庫纔會被真正加載進來。xcode
動態庫的優勢是,不須要拷貝到目標程序中,不會影響目標程序的體積,並且同一份庫能夠被多個程序使用(由於這個緣由,動態庫也被稱做共享庫)。同時,編譯時才載入的特性,也可讓咱們隨時對庫進行替換,而不須要從新編譯代碼。動態庫帶來的問題主要是,動態載入會帶來一部分性能損失,使用動態庫也會使得程序依賴於外部環境。若是環境缺乏動態庫或者庫的版本不正確,就會致使程序沒法運行(Linux 下喜聞樂見的 lib not found 錯誤)。安全
除了上面提到的 .a 和 .dylib 以外,Mac OS/iOS 平臺還可使用 Framework。Framework 其實是一種打包方式,將庫的二進制文件,頭文件和有關的資源文件打包到一塊兒,方便管理和分發。微信
在 iOS 8 以前,iOS 平臺不支持使用動態 Framework,開發者可使用的 Framework 只有蘋果自家的 UIKit.Framework,Foundation.Framework 等。這種限制多是出於安全的考慮(見這裏的討論)。換一個角度講,由於 iOS 應用都是運行在沙盒當中,不一樣的程序之間不能共享代碼,同時動態下載代碼又是被蘋果明令禁止的,沒辦法發揮出動態庫的優點,實際上動態庫也就沒有存在的必要了。app
因爲上面提到的限制,開發者想要在 iOS 平臺共享代碼,惟一的選擇就是打包成靜態庫 .a 文件,同時附上頭文件(例如微信的SDK)。可是這樣的打包方式不夠方便,使用時也比較麻煩,你們仍是但願共享代碼都能能像 Framework 同樣,直接扔到工程裏就能夠用。因而人們想出了各類奇技淫巧去讓 Xcode Build 出 iOS 可使用的 Framework,具體作法參考這裏和這裏,這種方法產生的 Framework 還有 「僞」(Fake) Framework 和 「真」(Real) Framework 的區別。性能
iOS 8/Xcode 6 推出以後,iOS 平臺添加了動態庫的支持,同時 Xcode 6 也原生自帶了 Framework 支持(動態和靜態均可以),上面提到的的奇技淫巧也就沒有必要了(新的作法參考這裏)。爲何 iOS 8 要添加動態庫的支持?惟一的理由大概就是 Extension 的出現。Extension 和 App 是兩個分開的可執行文件,同時須要共享代碼,這種狀況下動態庫的支持就是必不可少的了。可是這種動態 Framework 和系統的 UIKit.Framework 仍是有很大區別。系統的 Framework 不須要拷貝到目標程序中,咱們本身作出來的 Framework 哪怕是動態的,最後也仍是要拷貝到 App 中(App 和 Extension 的 Bundle 是共享的),所以蘋果又把這種 Framework 稱爲 Embedded Framework。
跟着 iOS8 / Xcode 6 同時發佈的還有 Swift。若是要在項目中使用外部的代碼,可選的方式只有兩種,一種是把代碼拷貝到工程中,另外一種是用動態 Framework。使用靜態庫是不支持的。
形成這個問題的緣由主要是 Swift 的 Runtime 沒有被包含在 iOS 系統中,而是會打包進 App 中(這也是形成 Swift App 體積大的緣由),靜態庫會致使最終的目標程序中包含重複的 Runtime(這是蘋果自家的解釋)。同時拷貝 Runtime 這種作法也會致使在純 ObjC 的項目中使用 Swift 庫出現問題。蘋果聲稱等到 Swift 的 Runtime 穩定以後會被加入到系統當中,到時候這個限制就會被去除了(參考這個問題 的問題描述,也是來自蘋果自家文檔)。
在純 ObjC 的項目中,CocoaPods 使用編譯靜態庫 .a 方法將代碼集成到項目中。在 Pods 項目中的每一個 target 都對應這一個 Pod 的靜態庫。不過在編譯過程當中並不會真的產出 .a 文件。若是須要 .a 文件的話,能夠參考這裏,或者使用 CocoasPods-Packager 這個插件。
當不想發佈代碼的時候,也可使用 Framework 發佈 Pod,CocoaPods 提供了 vendored_framework
選項來使用第三方 Framework,具體的作法能夠參考這裏和這裏。
對於 Swift 項目,CocoaPods 提供了動態 Framework 的支持,經過 use_frameworks!
選項控制。
更多有關代碼分發的擴展資料能夠參考這篇博客: http://geeklu.com/2014/02/objc-lib/