iOS 靜態庫(.a, .framework) 動態庫(.framework, dylib)
上面的文章回答了這幾個問題:
什麼是庫?
庫就是程式程式碼的集合, 將N個檔案組織起來, 是共享程式程式碼的一種方式-
庫的分類?
- 開源庫: 原始碼是公開的, 可以看到每個實現檔案 .m 的實現, 例如 Github 上常用的開源庫 AFNetworking, SDWebImage 等.
- 閉源庫: 不公開原始碼, 是經過編譯後的二進位制檔案, 看不到具體的實現. 閉源庫又分為: 靜態庫 和 動態庫
靜態庫的存在形式?
.a
.framework動態庫的存在形式?
.dylib
.framework-
靜態庫和動態庫的區別?
- .a 檔案肯定是靜態庫, .dylib 肯定是動態庫, .framework 可能是靜態庫也可能是動態庫
- 靜態庫在連結時, 會被完整的賦值到可執行檔案中, 如果多個APP都使用了同一個靜態庫, 那麼每個APP都會拷貝一份, 缺點是浪費記憶體, 類似於定義一個基本變數, 使用該基本變數是新複製了一份資料, 而不是原來定義的
- 動態庫不會複製,只有一份, 程式執行時動態載入到記憶體中, 系統只會載入一次, 多個程式公用一份, 節約了記憶體. 類似於使用變數的記憶體地址一樣. 使用的是同一個變數
但是專案中如果使用了自己定義的動態庫, 蘋果是不允許上架的, 在 iOS8 後 蘋果開放了動態載入 .dylib 的介面, 用於掛載 .dylib 動態庫
-
靜態庫的運用場景?
- 保護自己的核心程式碼, 如訊飛語音摸索了好多年探索出的結果當然要儲存起來, 都公開了公司怎麼生存
- 將MRC的專案打包成靜態庫, 可以在ARC下直接使用, 不用轉換, 如別人使用 MRC 寫的開源庫, 放到自己的ARC專案中, 需要對每個檔案加一個編譯引數
-fno-objc-arc
這樣相對來說很麻煩, 將整個工程打包成靜態庫直接放到專案中即可, 也不用對每個檔案新增編譯選項
靜態庫的特點?
.a + .h
.a : 可以看做所有 .m 檔案加密後的一個二進位制檔案
.h : 標頭檔案, 使用者暴露可用的介面 (方法)-
製作靜態庫的過程 .a
- new -> project -> Cocoa Touch Static Liabrary
- 編寫邏輯程式碼
- Build Phases -> Copy Files 新增要暴露的標頭檔案
- Build Setting -> Build Active Architecture only (只構建活躍構架) -> nO
- a. 所有模擬器除錯版本靜態庫: 選中模擬器 command + b
b. 真機除錯版本靜態庫: 選中 generic iOS Device , Command + b
c. 真機發布靜態庫: 選中 generic iOS Device , Edit scheme Run -> Build Configuration -> Release. command +b - 工程資料夾 Produts 下的 .a 檔案就是編譯得到的靜態檔案
- 右鍵 show finder 檢視所有版本的靜態庫
Debug-iphonesos 除錯 真機版本
Debug-iphonesimulator 除錯 模擬器版本
Release-iphoneos 釋出 真幾版本
Release-iphonesimulator 釋出 模擬器版本
8 . 如何引入靜態庫?
直接把 對應靜態庫 .a 和 暴露的.h 檔案 拖入到 目標工程中即可 - 合併靜態庫?
lipo -create 模擬器除錯.a 模擬器釋出.a 真機除錯.a 真機發布.a output 通用.a - 靜態庫注意:
自己的靜態庫給別人用, 一般都是給兩個釋出版本 (模擬器, 真機), 最好不要合併. 如果給了使用者合併版的, 使用者無法分解.
關於 lipo 命令
點選檢視lipo命令
關於構架:
構架是什麼?
CPU 構架 是 CPU 廠商給屬於同一系列的 CPU 產品定的一個規範, 主要目的是為了區分不同型別 CPU 的重要指示, 模擬器上的構架和真機上的構架不是一樣的, 模擬器和模擬器之間, 真機和真機之間的構架也是不同的, 如果靜態庫的構架和測試專案對應的模擬器或者真機上的構架不對應就會報錯 "Undefined symbols for architecture arm64/i386"
檢視靜態庫對應的構架: lipo -info Xxx.a
靜態庫都支援哪些構架?
模擬器架構
iPhone4s ~ 5 : i386
iPhone5s ~ 7Plus : x86_64
真機架構
3GS~4s : armv7
5/5c : armv7s(armv7相容armv7s)
5s ~ 6sPlus : arm64
- 靜態庫的製造過程 .framework
- new -> project -> Cocoa Touch Framework
- Build Settings -> Mach-O Type -> Static Library (預設是 Dynamic Library)
- 編寫邏輯程式碼
- 公開標頭檔案 Build Phases -> Headers -> 把Project 中需要暴露的 .h 檔案拖到 Public 中
- 將要公開的所有標頭檔案 引入到 總的標頭檔案 (庫名.h) 中,
- Build Setting -> Build Active Architecture Only -> NO
- 同 靜態庫.a 製作的步驟 5
- 專案資料夾 Products 下 的 庫名.framework 右鍵 show finder
- 同 .a 靜態庫製作的步驟7 得到所有型別版本的framework
- 將 需要的framework 拖入到目標工程中, 呼叫靜態庫的方法
2.動態庫 .framework
步驟跟 靜態庫 .framework 類似, 下面是不同的地方
1. Mach-O type -> Dynamic Library
將生成的動態庫 .framework 拖入到目標工程之後
2. General -> Embedded Binaries 中 新增該.framework
3. Linked Frameworks and libraries 中 會預設新增該 .framework
swift framework 動態庫 (swift 不支援靜態庫)
1. File --> project --> Cocoa Touch Framework (選擇swift 語言)
建立你需要的 swift 檔案. 完成程式碼邏輯
2. Build Phases --> Headers Public 中新增所有用得到的swift 檔案
要注意: 所有要暴露出來的swift 類和方法 都必須用public 修飾
3. Build Settings -> Mach-O type 選擇 Dynamic library (swift 語言智慧選擇動態庫)
4. Build Active Architecture Only 設為 NO
5. command + b 編譯一遍程式碼, 如果沒有問題的話, 動態庫已經生成好了
6. 工程資料夾 Products資料夾中 有個.framework 檔案, 選中, 右鍵 show finder
7. 可以拿到 .framework 檔案
8. 把 framework 檔案拖入要用到的工程中
9. General --> Embedded Binaries 中加入剛剛拖進去的 framework
10. 當framework 拖入工程後 xcode 會自動給 swift型別的 framework 建立一個檔案 (庫名-swift.h)
11. 工程中 引入 檔案 庫名-swift.h 後, 就可以呼叫所有 framework中暴露出來的 swift 方法.
更多詳細的介紹
- Swift完整專案打包Framework,嵌入OC專案使用
問題: Swift is not supported for static libraries. 不支援打包靜態庫
解決思路: - Swift打包靜態庫方法
上面的解決思路沒看懂, xcode 編譯後的檔案是什麼, 那麼,怎麼把編譯後的檔案加入靜態庫呢?
.bundle
使用第三方庫時 有可能會有一個.bundle 檔案, .bundle 其實是一個物理資料夾, 裡面可以放圖片等資源. 因為.bundle是一個物理資料夾 所以當被拖入到專案中就不會和自己專案中的圖片重名
.a 和 .framework
使用.a 時 需要同時將.a 和 .h 檔案拖入到工程中, 使用 .framework時 直接將這個資料夾拖入進去即可, 因為 .framework 資料夾中已經包含了 .h 檔案
.a + .h + .bundle = .framework 所以使用framework 更方便
相關文章
- iOS的Framework靜態庫iOSFramework
- iOS中的動態庫,靜態庫和framework介紹iOSFramework
- iOS - 靜態庫.a 和 framework 詳解iOSFramework
- ios靜態庫和動態庫iOS
- iOS動態庫和靜態庫的運用iOS
- 靜態庫與動態庫
- iOS 靜態庫 與私有庫iOS
- 動靜態庫
- cmake:生成靜態庫和動態庫
- Linux共享庫、靜態庫、動態庫詳解Linux
- linux下的靜態庫與動態庫Linux
- [Linux]動靜態庫Linux
- iOS逆向--注入framework庫到appiOSFrameworkAPP
- linux 動態庫 靜態庫 函式覆蓋Linux函式
- android下java的靜態庫和動態庫AndroidJava
- 動態連結庫與靜態連結庫
- iOS中動/靜態庫支援bitcode的問題iOS
- 一、靜態庫和動態庫,Makefile專案管理專案管理
- 簡述Linux下的靜態庫和動態庫Linux
- iOS使用指令碼跟隨工程程式碼動態生成FrameworkiOS指令碼Framework
- 筆記: 判斷lib庫是動態庫還是靜態庫筆記
- Android NDK祕籍--淺析靜態庫和動態庫Android
- iOS 靜態庫詳解與開發iOS
- 自建 iOS 靜態庫並用 pod 管理iOS
- ABAP程式碼靜態分析工具SQF - Support Query FrameworkFramework
- iOS動態庫的使用iOS
- 靜態庫生成
- Android NDK祕籍--編譯靜態庫、呼叫靜態庫Android編譯
- Android:JNI與NDK(二)交叉編譯與動態庫,靜態庫Android編譯
- C靜態庫的建立與使用--為什麼要引入靜態庫?
- 靜態庫和動態庫的製作以及Bundle資原始檔的使用
- 封裝動態庫dll與靜態庫lib(原理及簡單例項)封裝單例
- 理解alivc_framework狀態機Framework
- 靜態資源公共庫
- 深入iOS系統底層之靜態庫介紹iOS
- iOS應用程式瘦身的靜態庫解決方案iOS
- iOS-靜態庫聯調中的若干問題iOS
- linux下靜態連結庫和動態連結庫的區別有哪些Linux
- 玩轉 iOS 開發:Aggregate 指令碼版本《模擬器與真機靜態 Framework 合成教程》iOS指令碼Framework