一、靜態(tài)庫和動態(tài)庫的區(qū)別
庫:是資源文件和代碼編譯的一個集合
靜態(tài)庫: 靜態(tài)庫是在編譯時,完整的拷貝至可執(zhí)行文件中,被多次使用就有多次冗余拷貝;
動態(tài)庫: 程序運行時由系統(tǒng)動態(tài)加載到內(nèi)存,而不是復(fù)制,供程序調(diào)用。系統(tǒng)只加載一次,多個程序共用,節(jié)省內(nèi)存。因此,編譯內(nèi)容更小,而且因為動態(tài)庫是需要時才被引用,所以更快。
靜態(tài)和動態(tài)的名字,區(qū)分了編譯后的代碼是以何種方式鏈接到目標(biāo)程序中的。
二、靜態(tài)庫和動態(tài)庫的形式
靜態(tài)庫:.a和.framework
動態(tài)庫: .dylib和.framework
framework為什么可能是動態(tài)庫,也可能是靜態(tài)庫?系統(tǒng)的.framework是動態(tài)庫, 我們自己建立的.framework是靜態(tài)庫。
Bundle的概念,framework是一種特殊類型的Bundle,bunlde是一個包含多個子文件夾的文件夾。在iOS上,Bundlue將相關(guān)聯(lián)的文件(比如圖片, Nibs,代碼)編譯成一個包文件。程序?qū)⑺?dāng)作一個單獨文件來處理,你可以在不知道內(nèi)部實現(xiàn)的情況下使用它。
而庫需要一些其他資源:頭文件,本地化文件,圖片資源,文檔和示例。我們可以將其打包成一個bunlde,這就是framework。
靜態(tài)庫包含靜態(tài)資源包,動態(tài)庫包含動態(tài)資源包,而且動態(tài)庫可能包含同一個動態(tài)資源包的不同版本。
三、EMBEDDED, UNBRELLA, MODULAR
即使我們將資源文件(圖片等)打包到frameworks里,Xcode仍然未能引用它們。通過embedding framework讓我們可以訪問這些資源文件,操作步驟見鏈接 add your framework in the "Embed Frameworks" section.
Umbrella frameworks的定義: Umbrella frameworks add minor refinements to the standard framework structure, such as the ability to encompass other frameworks
umberllar framework的目的是 隱藏不同frameworks之間的復(fù)雜依賴關(guān)系。它允許你將不同的frameworks合并成一個framework,輸出部分頭文件。為了構(gòu)建一個umbrella framework,你必須包含umbrella header。
為了能夠引入framework modular,我們必須引入 module map
framework module ModularFramework{
module Modulel{
header "File1.h"
}
module Module2{
header "File2.h"
}
}
隨后,使用module
import ModularFramework.Module1
import ModularFramework.Module2
CocoaPods允許使用umbrella和modular frameworks。如果你引入了pods到你的項目里,在Target->YourApp->Build Settings找查找modulemap和umbrella可以看到它們的設(shè)置。
四、CocoaPods相關(guān)
- 在
Podfile中
默認(rèn)使用靜態(tài)庫,即 # use_frameworks!(#是注釋標(biāo)示)
添加use_frameworks!表明Pod使用動態(tài)庫, Pods/Products里都是動態(tài)庫(.framework文件)
不添加use_frameworks!表明Pod使用靜態(tài)庫, Pods/Products里都是靜態(tài)庫(.a文件)

- 在使用靜態(tài)庫時,某些Pod不支持module怎么辦?
可以使用use_modular_headers!來讓所有Pod支持靜態(tài)庫;
或者對不支持靜態(tài)庫的Pod后面添加:modular_headers => true來使其支持module
五、#import和@import
可以先看個例子:
@import MapKit;
@import MapKit.MKAnnotation;
#import <MapKit/MKAnnotation.h>
@import是iOS7之后的新特性與法: Modules(模塊導(dǎo)入)或者"語義引入"。Modules可以看成是可執(zhí)行framework的集合,比#import更加快捷和高效。Enable Modules是默認(rèn)打開的,在Target->YourApp->Build Setting->搜索Modules, 可以看到Enable Modules默認(rèn)是YES,Link Frameworks Automatically也是默認(rèn)打開的。打開后,使用原來的#import和#include,編譯器會在編譯的時候自動把可能的地方換成modules的寫法去編譯。
@import的一個優(yōu)勢是開發(fā)者不需要手動將framework添加到project settings里面,它是自動完成的。
使用Modules的形式,可以使用@import MapKit;, 還可以只加載framework里的submodules,如@import MapKit.MKAnnotation;
六、常見問題
Q:可以在runtime時加載動態(tài)庫嗎?
A:不可以(除非你不想上AppStore)。蘋果不允許在審核后更改app的行為,類似于熱修復(fù).
Q: 可以用Swift創(chuàng)建靜態(tài)庫嗎?
A:在Xcode9后,可以。CocoaPods 1.5.0也支持Swift Static Framework.
Q:我可以使用多少動態(tài)庫?有限制嗎?
A:我們建議將動態(tài)庫控制在一定范圍內(nèi)。雖然有可能創(chuàng)建很多的動態(tài)庫,但是建議盡量不要創(chuàng)建太多的動態(tài)庫,而使用靜態(tài)庫。
Q: Podfile使用靜態(tài)庫時出現(xiàn)報錯[!] The following Swift pods cannot yet be integrated as static libraries:,如何解決?
A:pod install 時的錯誤信息提示我們應(yīng)該使用use_modular_headers!來讓整個項目支持靜態(tài)庫,或者對單個Pod使用:modular_headers => true