一、基本概念
1.什麼是庫?
庫是共享程式程式碼的方式,一般分為靜態庫和動態庫。
2.靜態庫與動態庫的區別?
(1)靜態庫:之所以叫做靜態,是因為靜態庫在編譯的時候會被直接拷貝一份,複製到目標程式裡,這段程式碼在目標程式裡就不會再改變了。
靜態庫的好處很明顯,編譯完成之後,庫檔案實際上就沒有作用了。目標程式沒有外部依賴,直接就可以執行。當然其缺點也很明顯,就是會使用目標程式的體積增大。被多次使用就有多份冗餘拷貝。
(2)動態庫:連結時不復制,程式執行時由系統動態載入到記憶體,供程式呼叫,系統只載入一次,多個程式共用,節省記憶體。
動態庫的優點是,不需要拷貝到目標程式中,不會影響目標程式的體積,而且同一份庫可以被多個程式使用(因為這個原因,動態庫也被稱作共享庫)。同時,編譯時才載入的特性,也可以讓我們隨時對庫進行替換,而不需要重新編譯程式碼。動態庫帶來的問題主要是,動態載入會帶來一部分效能損失,使用動態庫也會使得程式依賴於外部環境。如果環境缺少動態庫或者庫的版本不正確,就會導致程式無法執行(Linux 下常見 lib not found 錯誤)。
在 iOS8 之後,蘋果開始支援開發自己的 framework
。
此時自己構建的 framework
和系統的 framework
還是有區別的,系統的 framework 並不需要複製到目標程式。
自己開發的 framework
無論是動態還是靜態的,都要複製到目標程式,所以蘋果又把這個叫做 embeded framework
。
3.iOS 裡靜態庫形式?
.a
和.framework
4.iOS 裡動態庫形式?
.dylib
和.framework
5.framework 為什麼既是靜態庫又是動態庫?
系統的.framework
是動態庫,我們自己建立的.framework
是靜態庫。
6.a與.framework 有什麼區別?
.a
是一個純二進位制檔案,.framework
中除了有二進位制檔案之外還有資原始檔。
.a
檔案不能直接使用,至少要有.h
檔案配合,.framework
檔案可以直接使用。
.a
+ .h
+ sourceFile
= .framework
。
建議用.framework
。
7.為什麼要使用靜態庫?
方便共享程式碼,便於合理使用。
實現 iOS 程式的模組化。可以把固定的業務模組化成靜態庫。
和別人分享你的程式碼庫,但不想讓別人看到你程式碼的實現。
開發第三方 sdk
的需要。
8.製作靜態庫時的幾點注意:
1 注意理解:無論是.a
靜態庫還.framework
靜態庫,我們需要的都是二進位制檔案+.h
+其它資原始檔的形式,不同的是,.a
本身就是二進位制檔案,需要我們自己配上.h
和其它檔案才能使用,而.framework
本身已經包含了.h
和其它檔案,可以直接使用。
2 圖片資源的處理:兩種靜態庫,一般都是把圖片檔案單獨的放在一個.bundle
檔案中,一般.bundle
的名字和.a
或.framework
的名字相同。.bundle
檔案很好弄,新建一個資料夾,把它改名為.bundle
就可以了,右鍵,顯示包內容可以向其中新增圖片資源。
3 category
是我們實際開發專案中經常用到的,把 category
打成靜態庫是沒有問題的,但是在用這個靜態庫的工程中,呼叫 category
中的方法時會有找不到該方法的執行時錯誤(selector not recognized),解決辦法是:在使用靜態庫的工程中配置 other linker flags
的值為-ObjC
。
4 如果一個靜態庫很複雜,需要暴露的.h
比較多的話,就可以在靜態庫的內部建立一個.h
檔案(一般這個.h
檔案的名字和靜態庫的名字相同),然後把所有需要暴露出來的.h 檔案都集中放在這個.h 檔案中,而那些原本需要暴露的.h
都不需要再暴露了,只需要把.h
暴露出來就可以了。
二、製作.a 靜態庫
1.新建工程,選擇 Cocoa Touch Static Library,建立.a 靜態庫
2.配置工程環境
2.1 配置最低支援版本
2.2 設定適配所有模擬器架構重要
project -> buildSeting -> Build Active Architecture Only 設為NO
Build Active Architecture Only:指定是否只對當前連線裝置所支援的指令集編譯 設定為 YES,是為了 Debug 的時候編譯速度更快,它只編譯當前的 Architecture 版本,而設定為 NO 時,會編譯所有的版本。 所以,一般預設 Debug 設定為 YES,Release 時為 NO,以適應不同裝置。但是我們是在 Debug 模式下建立所有機型都可執行的靜態庫,所以我們要把 Bebug 下設定 NO。若為 YES,那麼編譯出來的.a 靜態庫就只包含當前裝置的指令集。
3.新增自己要封裝的檔案
標頭檔案最好一起放在一個.h 檔案中,方便使用時只匯入一個h 檔案,這裡放在 TestStaticHeader 裡;
如果需要用到圖片,可以新增 Bundle 檔案:
4.修改專案配置,把要暴露的 .h 檔案,新增到 Target-> Build Phases -> Copy Files
新增暴露的標頭檔案的另一種方式,是新增 Headers 裡的 Public 中:
5.生成.a 檔案
此處注意需要生成 4 個
5.1修改環境
5.2 選擇模擬器+Debug 環境+“cmd+R”生成.a
此處注意需要生成4個 如此類推打出四種.a
- 真機-Debug版本
- 真機-Release版本
- 模擬器-Debug版本
- 模擬器-Release版本
最終生成結果:
5.3 合併 debug 兩個包和 release 兩個包
注意:這裡的合併指的是 1.debug 下真機+模擬器合併 2.release 下真機+模擬器合併
(1)將4個.a檔案拷貝到單獨資料夾
(2)合併
開啟終端,切到上述資料夾目錄,執行以下語句
lipo -create+空格+模擬器Debug路徑+空格+模擬器Release路徑+空格-output+空格+輸出路徑+輸出名字(可自定義)
複製程式碼
同理 release 也是如此,最後生成兩個檔案
好了,這樣就建立完.a 靜態庫了,使用的時候,只需在工程中匯入.a 檔案和暴露的.h 檔案,配置 Header search path 路徑就可以了。
注意:如果靜態庫中有 category 類,則在使用靜態庫的專案配置中【Other Linker Flags】需要新增引數【-ObjC]或者【-all_load】。 為了開發方便,我們可以使用生成的通用靜態庫,但是最終上線的使用我們可以只匯入真機的,這樣工程的體積也會小一些。
三、製作 framework 靜態庫
1.新建 framework 工程
2.新建檔案類
3.修改工程檔案配置
build setting ->搜尋 mach -> 修改 mach -O Type ->static Library
⚠️注意:如果需要匯入第三方靜態庫,在拖入工程新增的時候,不要勾選新增到target中。
4.暴露標頭檔案
5.生成 .framework
5.1 修改環境
這裡可以選擇 Debug 和 Release 環境
5.2 選擇模擬器+Debug 環境+“cmd+R”生成.a
此處注意需要生成4個 如此類推打出四種.framework
- 真機-Debug版本
- 真機-Release版本
- 模擬器-Debug版本
- 模擬器-Release版本
最終生成結果
6.合併 debug 兩個包和 release 兩個包
注意:這裡的合併指的是 1.debug 下真機+模擬器合併 2.release 下真機+模擬器合併
6.1 將 4 個 .framework 檔案拷貝到單獨資料夾
6.2 合併
開啟終端,輸入命令規則
lipo -create+空格+模擬器Debug路徑+空格+模擬器Release路徑+空格-output+空格+輸出路徑+輸出名字(可自定義)
//For example:
lipo -create /Users/Kaaaaai/Desktop/frameworkProduct/TestStatic_framework-Debug-iphoneos /Users/Kaaaaai/Desktop/frameworkProduct/TestStatic_framework-Debug-iphonesimulator -output /Users/Kaaaaai/Desktop/frameworkProduct/TestStatic_framework-Debug
複製程式碼
同理 release 也是如此,最後生成兩個檔案。
6.3替換檔案
(1)尋找之前生成的 任意framework (2)替換二進位制檔案
替換前:
替換後:
大功告成。