什么是庫(kù)?
庫(kù)就是程序代碼的集合, 將N個(gè)文件組織起來(lái), 是共享程序代碼的一種方式
庫(kù)的分類(lèi)?
開(kāi)源庫(kù): 源碼是公開(kāi)的, 可以看到每個(gè)實(shí)現(xiàn)文件 .m 的實(shí)現(xiàn), 例如 Github 上常用的開(kāi)源庫(kù) AFNetworking, SDWebImage 等.
閉源庫(kù): 不公開(kāi)源碼, 是經(jīng)過(guò)編譯后的二進(jìn)制文件, 看不到具體的實(shí)現(xiàn). 閉源庫(kù)又分為: 靜態(tài)庫(kù) 和 動(dòng)態(tài)庫(kù)
靜態(tài)庫(kù)的存在形式?
.a
.framework
動(dòng)態(tài)庫(kù)的存在形式?
.dylib
.framework
靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別?
.a 文件肯定是靜態(tài)庫(kù), .dylib 肯定是動(dòng)態(tài)庫(kù), .framework 可能是靜態(tài)庫(kù)也可能是動(dòng)態(tài)庫(kù)
靜態(tài)庫(kù)在鏈接時(shí), 會(huì)被完整的賦值到可執(zhí)行文件中, 如果多個(gè)APP都使用了同一個(gè)靜態(tài)庫(kù), 那么每個(gè)APP都會(huì)拷貝一份, 缺點(diǎn)是浪費(fèi)內(nèi)存, 類(lèi)似于定義一個(gè)基本變量, 使用該基本變量是新復(fù)制了一份數(shù)據(jù), 而不是原來(lái)定義的
動(dòng)態(tài)庫(kù)不會(huì)復(fù)制,只有一份, 程序運(yùn)行時(shí)動(dòng)態(tài)加載到內(nèi)存中, 系統(tǒng)只會(huì)加載一次, 多個(gè)程序公用一份, 節(jié)約了內(nèi)存. 類(lèi)似于使用變量的內(nèi)存地址一樣. 使用的是同一個(gè)變量
但是項(xiàng)目中如果使用了自己定義的動(dòng)態(tài)庫(kù), 蘋(píng)果是不允許上架的, 在 iOS8 后 蘋(píng)果開(kāi)放了動(dòng)態(tài)加載 .dylib 的接口, 用于掛載 .dylib 動(dòng)態(tài)庫(kù)
靜態(tài)庫(kù)的運(yùn)用場(chǎng)景?
保護(hù)自己的核心代碼, 如訊飛語(yǔ)音摸索了好多年探索出的結(jié)果當(dāng)然要保存起來(lái), 都公開(kāi)了公司怎么生存
將MRC的項(xiàng)目打包成靜態(tài)庫(kù), 可以在ARC下直接使用, 不用轉(zhuǎn)換, 如別人使用 MRC 寫(xiě)的開(kāi)源庫(kù), 放到自己的ARC項(xiàng)目中, 需要對(duì)每個(gè)文件加一個(gè)編譯參數(shù)-fno-objc-arc這樣相對(duì)來(lái)說(shuō)很麻煩, 將整個(gè)工程打包成靜態(tài)庫(kù)直接放到項(xiàng)目中即可, 也不用對(duì)每個(gè)文件添加編譯選項(xiàng)
靜態(tài)庫(kù)的特點(diǎn)?
.a + .h
.a : 可以看做所有 .m 文件加密后的一個(gè)二進(jìn)制文件
.h : 頭文件, 用戶(hù)暴露可用的接口 (方法)
制作靜態(tài)庫(kù)的過(guò)程 .a
new -> project -> Cocoa Touch Static Liabrary
編寫(xiě)邏輯代碼
Build Phases -> Copy Files 添加要暴露的頭文件
Build Setting -> Build Active Architecture only (只構(gòu)建活躍構(gòu)架) -> nO
a. 所有模擬器調(diào)試版本靜態(tài)庫(kù): 選中模擬器 command + b
b. 真機(jī)調(diào)試版本靜態(tài)庫(kù): 選中 generic iOS Device , Command + b
c. 真機(jī)發(fā)布靜態(tài)庫(kù): 選中 generic iOS Device , Edit scheme Run -> Build Configuration -> Release.? ? command +b
工程文件夾 Produts 下的 .a 文件就是編譯得到的靜態(tài)文件
右鍵 show finder 查看所有版本的靜態(tài)庫(kù)
Debug-iphonesos 調(diào)試 真機(jī)版本
Debug-iphonesimulator 調(diào)試 模擬器版本
Release-iphoneos 發(fā)布 真幾版本
Release-iphonesimulator 發(fā)布 模擬器版本
8 . 如何引入靜態(tài)庫(kù)?
直接把 對(duì)應(yīng)靜態(tài)庫(kù) .a? 和 暴露的.h 文件 拖入到 目標(biāo)工程中即可
合并靜態(tài)庫(kù)?
lipo -create 模擬器調(diào)試.a 模擬器發(fā)布.a 真機(jī)調(diào)試.a 真機(jī)發(fā)布.a output 通用.a
靜態(tài)庫(kù)注意:
自己的靜態(tài)庫(kù)給別人用, 一般都是給兩個(gè)發(fā)布版本 (模擬器, 真機(jī)), 最好不要合并. 如果給了用戶(hù)合并版的, 用戶(hù)無(wú)法分解.
關(guān)于 lipo 命令
關(guān)于構(gòu)架:
構(gòu)架是什么?
CPU 構(gòu)架 是 CPU 廠商給屬于同一系列的 CPU 產(chǎn)品定的一個(gè)規(guī)范, 主要目的是為了區(qū)分不同類(lèi)型 CPU? 的重要指示, 模擬器上的構(gòu)架和真機(jī)上的構(gòu)架不是一樣的, 模擬器和模擬器之間, 真機(jī)和真機(jī)之間的構(gòu)架也是不同的, 如果靜態(tài)庫(kù)的構(gòu)架和測(cè)試項(xiàng)目對(duì)應(yīng)的模擬器或者真機(jī)上的構(gòu)架不對(duì)應(yīng)就會(huì)報(bào)錯(cuò) "Undefined symbols for architecture arm64/i386"
查看靜態(tài)庫(kù)對(duì)應(yīng)的構(gòu)架: lipo -info Xxx.a
靜態(tài)庫(kù)都支持哪些構(gòu)架?
模擬器架構(gòu)
? ? iPhone4s ~ 5 : i386
? ? iPhone5s ~ 7Plus : x86_64
真機(jī)架構(gòu)
? ? 3GS~4s : armv7
? ? 5/5c : armv7s(armv7兼容armv7s)
? ? 5s ~ 6sPlus : arm64
模擬器32位處理器測(cè)試需要i386架構(gòu)宵膨,
模擬器64位處理器測(cè)試需要x86_64架構(gòu)汗盘,
真機(jī)32位處理器需要armv7,或者armv7s架構(gòu),
真機(jī)64位處理器需要arm64架構(gòu)澜建。
靜態(tài)庫(kù)的制造過(guò)程 .framework
new -> project -> Cocoa Touch Framework
Build Settings -> Mach-O Type -> Static Library (默認(rèn)是 Dynamic Library)
編寫(xiě)邏輯代碼
公開(kāi)頭文件 Build Phases -> Headers -> 把Project 中需要暴露的 .h 文件拖到 Public 中
將要公開(kāi)的所有頭文件 引入到 總的頭文件 (庫(kù)名.h) 中,
Build Setting -> Build Active Architecture Only -> NO
同 靜態(tài)庫(kù).a 制作的步驟 5
項(xiàng)目文件夾 Products 下 的 庫(kù)名.framework 右鍵 show finder
同 .a 靜態(tài)庫(kù)制作的步驟7 得到所有類(lèi)型版本的framework
將 需要的framework 拖入到目標(biāo)工程中, 調(diào)用靜態(tài)庫(kù)的方法
2.動(dòng)態(tài)庫(kù) .framework
步驟跟 靜態(tài)庫(kù) .framework 類(lèi)似, 下面是不同的地方
1. Mach-O type -> Dynamic Library
將生成的動(dòng)態(tài)庫(kù) .framework 拖入到目標(biāo)工程之后
2. General -> Embedded Binaries 中 添加該.framework
3. Linked Frameworks and libraries 中 會(huì)默認(rèn)添加該 .framework
swift framework 動(dòng)態(tài)庫(kù) (swift 不支持靜態(tài)庫(kù))
1. File --> project --> Cocoa Touch Framework (選擇swift 語(yǔ)言)
創(chuàng)建你需要的 swift 文件. 完成代碼邏輯
2. Build Phases --> Headers Public 中添加所有用得到的swift 文件
要注意: 所有要暴露出來(lái)的swift 類(lèi)和方法 都必須用public 修飾
3. Build Settings -> Mach-O type 選擇 Dynamic library (swift 語(yǔ)言智能選擇動(dòng)態(tài)庫(kù))
4. Build Active Architecture Only? 設(shè)為 NO
5. command + b? 編譯一遍代碼, 如果沒(méi)有問(wèn)題的話(huà), 動(dòng)態(tài)庫(kù)已經(jīng)生成好了
6. 工程文件夾 Products文件夾中 有個(gè).framework 文件, 選中, 右鍵 show finder
7. 可以拿到 .framework 文件
8. 把 framework 文件拖入要用到的工程中
9. General --> Embedded Binaries 中加入剛剛拖進(jìn)去的 framework
10. 當(dāng)framework 拖入工程后 xcode 會(huì)自動(dòng)給 swift類(lèi)型的 framework 創(chuàng)建一個(gè)文件 (庫(kù)名-swift.h)
11. 工程中 引入 文件 庫(kù)名-swift.h 后, 就可以調(diào)用所有 framework中暴露出來(lái)的 swift 方法.
有時(shí)候項(xiàng)目需要在集成C++靜態(tài)庫(kù)的基礎(chǔ)之上,去用OC進(jìn)行封裝暴露對(duì)外的接口,實(shí)現(xiàn)iOS中SDK的完成。
在C++編譯靜態(tài)庫(kù)的過(guò)程中琼了,有個(gè)bitcode選項(xiàng)要注意,用C++編譯靜態(tài)庫(kù)的時(shí)候困曙,盡量支持bitcode否則表伦,你在鏈接的時(shí)候會(huì)出現(xiàn)錯(cuò)誤谦去。你需要設(shè)置工程中target的Enable Bitcode為NO才可以正常編譯慷丽。
在程序支持的編譯框架中可以在Architectures中選擇arm64 /arm64e/armv7...
Xcode設(shè)置項(xiàng)之Architectures和Valid Architectures和Build Active?Architectures Only參數(shù)的選擇 應(yīng)當(dāng)特別注意
項(xiàng)目中編譯c++文件的時(shí)候,需要修改項(xiàng)目中任意一個(gè).m文件的后綴為.mm否則編譯不通過(guò)
項(xiàng)目中的資源文件應(yīng)該放在bundle文件中鳄哭,利用oc中的從bundle文件中取資源的方式存取要糊。