什么是 庫 ?
庫就是程序代碼的集合, 將 N 個文件組織起來, 是共享程序代碼的一種方式。庫的分類?
開源庫: 源碼是公開的, 可以看到每個實現文件 .m 的實現,
例如 Github 上常用的開源庫 AFNetworking, SDWebImage 等.
閉源庫: 不公開源碼, 是經過編譯后的二進制文件, 看不到具體的實現.
閉源庫 又分為: 靜態庫 和 動態庫
靜態庫的存在形式?
.a
.framework動態庫的存在形式?
.dylib
.framework ( 系統直接提供給我們的 framework 都是動態庫!)
.tbd靜態庫的特點?
.a + .h
.a : 可以看做所有 .m 文件加密后的一個二進制文件
.h : 頭文件, 用戶暴露可用的接口 (方法)理解:
.a 是一個純二進制文件,
.framework 中除了有二進制文件之外還有資源文件。
.a 要有 .h 文件以及資源文件配合使用,
.framework 文件 可以直接使用。
總的來說,.a + .h + sourceFile = .framework。所以創建靜態庫最好還是用.framework的形式
靜態庫 和 動態庫 的區別?
.a 文件肯定是靜態庫,
.dylib 肯定是動態庫,
.framework 可能是靜態庫也可能是動態庫。不同點:
1、靜態庫在鏈接時, 會被完整的賦值到可執行文件中, 如果多個 APP 都使用了同一個靜態庫, 那么每個 APP 都會拷貝一份, 缺點是浪費內存, 類似于定義一個基本變量, 使用該基本變量是新復制了一份數據, 而不是原來定義的
2、動態庫不會復制, 只有一份, 程序運行時動態加載到內存中, 系統只會加載一次, 多個程序公用一份, 節約了內存. 類似于使用變量的內存地址一樣. 使用的是同一個變量
3、但是項目中如果使用了自己定義的動態庫, 蘋果是不允許上架的, 在 iOS 8 后 蘋果開放了動態加載 .dylib 的接口, 用于掛載 .dylib 動態庫共同點:
靜態庫和動態庫都是閉源庫,只能拿來滿足某個功能的使用,不會暴露內部具體的代碼信息
- 靜態庫的運用場景?
保護自己的核心代碼, 如訊飛語音摸索了好多年探索出的結果當然要保存起來, 都公開了公司怎么生存
將 MRC 的項目打包成靜態庫, 可以在 ARC 下直接使用, 不用轉換, 如別人使用 MRC 寫的開源庫, 放到自己的 ARC 項目中, 需要對每個文件加一個編譯參數 -fno-objc-arc 這樣相對來說很麻煩, 將整個工程打包成 靜態庫 直接放到項目中即可, 也不用對每個文件添加編譯選項
iOS 開發中 靜態庫 & 動態庫 區別:
靜態庫 & 動態庫 是相對 編譯期 和 運行期 的:
靜態庫在程序編譯時會被鏈接到目標代碼中,程序運行時將不再需要改靜態庫;而動態庫在程序編譯時并不會被鏈接到目標代碼中,只是在程序運行時才被載入,因為在程序運行期間還需要動態庫的存在。
從源代碼到 app ,當我們點擊了 build 之后,做了什么事情呢?
預處理(Pre-process):把宏替換,刪除注釋,展開頭文件,產生 .i 文件。
編譯(Compliling):把之前的 .i 文件轉換成匯編語言,產生 .s文件。
匯編(Asembly):把匯編語言文件轉換為機器碼文件,產生 .o 文件。
鏈接(Link):對.o文件中的對于其他的庫的引用的地方進行引用,生成最后的可執行文件(同時也包括多個 .o 文件進行 link)。
靜態庫 好處:
模塊化,分工合作,提高了代碼的復用及核心技術的保密程度
避免少量改動經常導致大量的重復編譯連接
也可以重用,注意不是共享使用動態庫 好處:
使用動態庫,可以將最終可執行文件體積縮小,將整個應用程序分模塊,團隊合作,進行分工,影響比較小
使用動態庫,多個應用程序共享內存中得同一份庫文件,節省資源
使用動態庫,可以不重新編譯連接可執行程序的前提下,更新動態庫文件達到更新應用程序的目的。
應用插件化
軟件版本實時模塊升級
在其它大部分平臺上,動態庫都可以用于不同應用間共享, 共享可執行文件,這就大大節省了內存。
動態庫的處理方式
首先,對于動態庫而言其實分 動態鏈接庫 和 動態加載庫 兩種的,這兩個最本質的區別還是加載時間。動態鏈接庫:在沒有被加載到內存的前提下,當可執行文件被加載,動態庫也隨著被加載到內存中。在 Linked Framework and Libraries 設置的一些 share libraries。【隨著程序啟動而啟動】
動態加載庫:當需要的時候再使用 dlopen 等通過代碼或者命令的方式來加載。【在程序啟動之后】
但是不論是哪種動態庫,相比較與靜態庫,動態庫處理起來要棘手的多。由于動態庫是動態的,所以你事先不知道某個函數的具體地址。因此動態鏈接器在鏈接函數的時候需要做大量的工作。
動態庫動態更新問題
能否動態庫的方式來動態更新AppStore上的版本呢?
framework 本來是蘋果專屬的內部提供的動態庫文件格式,但是自從 2014 年 WWDC 之后,開發者也可以自定義創建 framework 實現動態更新(繞過apple store審核,從服務器發布更新版本)的功能,這與蘋果限定的上架的 app 必須經過 apple store 的審核制度是沖突的,所以含有自定義的framework 的 app 是無法在商店上架的,但是如果開發的是企業內部應用,就可以考慮嘗試使用動態更新技術來將多個獨立的 app 或者功能模塊集成在一個 app 上面!(我開發的就是企業內部使用的 app,我們將企業官網中的板塊開發成4個獨立的app,然后將其改造為 framework 文件最終集成在一款平臺級的 app 當中進行使用,這樣就可以在一款 app 上面使用原本 4 個 app 的全部功能!)
使用自定義的動態庫的方式來動態更新只能用在 in house(企業發布) 和 develop 模式,卻但不能在使用到 AppStore ,因為在上傳打包的時候,蘋果會對我們的代碼進行一次 Code Singing,包括 app 可執行文件和所有 Embedded 的動態庫。因此,只要你修改了某個動態庫的代碼,并重新簽名,那么 MD5 的哈希值就會不一樣,在加載動態庫的時候,蘋果會檢驗這個 hash 值,當蘋果監測到這個動態庫非法時,就會造成 Crash
在制作 framework 的時候需要選擇這個 Mach-O Type.
為 Mach Object 文件格式的縮寫,它是一種用于可執行文件,目標代碼,動態庫,內核轉儲的文件格式。作為a.out格式的替代,Mach-O提供了更強的擴展性,并提升了符號表中信息的訪問速度。