iOS的靜態(tài)庫和動態(tài)庫

一、靜態(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找查找modulemapumbrella可以看到它們的設(shè)置。

四、CocoaPods相關(guān)

  1. 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文件)

use_frameworks的效果

  1. 在使用靜態(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

參考鏈接

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

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

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