標籤:
簡介
什麼是庫?
-
根據原始碼的公開情況,庫可以分為2種類型
- 開源庫
- 公開原始碼,能看到具體實現
- 比如SDWebImage、AFNetworking
- 閉源庫
- 不公開原始碼,是經過編譯後的二進位檔案,看不到具體實現
- 主要分為:靜態庫、動態庫
-
為什麼製作閉源庫
- 國內的企業,掌握有核心技術,同時是又希望更多的程式員來使用其技術,因此採用"閉源"的方式開發使用 例如:百度地圖,友盟,JPush等
- 在企業開發中,一些核心技術或者常用架構,出於安全性和穩定性的考慮,也會提供靜態庫給程式員使用
- 靜態庫與動態庫
- 靜態庫和動態庫的存在形式
- 靜態庫:.a 和 .framework
- 動態庫:.dylib(Xcode7.0之前) .tbd[Xcode7以後] 和 .framework
- 靜態庫和動態庫在使用上的區別
- 靜態庫:連結時,靜態庫會被完整地複製到可執行檔中,被多個應用使用就有多份冗餘拷貝(左圖所示)
- 動態庫:連結時不複製,程式運行時由系統動態載入到記憶體,供程式調用,系統只載入一次,多個程式共用,節省記憶體(右圖所示)
-
-
- 3.需要注意的是:項目中如果使用了自製的動態庫,在Xcode6之前不能被上傳到AppStore,Xcode6以後可以上傳AppStore
靜態庫
靜態庫的特點
.a +.h
製作靜態庫簡單演練
-
步驟
-
- 建立一個Tools的靜態庫項目
-
建立一個類方法,實現簡單的加法
+ (double) sumNum1:(double) x andNum2:(double) y;
+ (double)sumNum1:(double)x andNum2:(double)y { return x + y; }
- 編譯: 注意,在編譯靜態庫時,需要編譯兩個版本 ->
真機(arm) | 模擬器(i386)
- 查看檔案導覽列->Product->libTools.a檔案,如果為
紅色表示沒有產生.a檔案,如果是黑色表示產生了.a檔案
- 僅僅編譯模擬器不會產生.a,需要在真機下編譯才能產生.a檔案
- 選中.a檔案->右擊->showFinder ,產生兩個.a檔案,一個用於真機,一個用於模擬器
-
測試產生的靜態庫
-
建立ToolsTest的iOS項目
- 將編譯產生的模擬器的.a + .h拖到項目中使用
- 在ViewController.m匯入Tools.h檔案
- 使用調用類方法 + (double) sumNum1:(double) x andNum2:(double) y;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ double rs = [Tools sumNum1:10.4 andNum2:20.5]; NSLog(@"%lf",rs);}
輸出結果:30.9
帶有資源的靜態庫
-
步驟:簡單靜態庫的基礎上
- 建立一個資源工具類CZResourceTools
- 匯入圖片資源
-
提供擷取圖片資源的方法
+ (UIImage *) logoOfItcast;+ (UIImage *) logoOfItheima;+ (UIImage *) lufei;
-
編譯,編譯後的include檔案夾中沒有我們剛剛添加的CZResourceTools.h檔案,解決方案 項目->TARGETS->Build Phases->Copy Files->添加 需要標頭檔
-
- 測試,修改測試測試專案
- 刪除之前置入.h+.a檔案
- 匯入新產生的 .h + .a 檔案
- 在ViewController匯入CZResourceTools.h
- 實現如下代碼
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ UIImage *image = [CZResourceTools logoOfItcast]; NSLog(@"%@",image);}
5.點擊螢幕輸出內容為:
ToolsTest[2260:252976] (null)
這是因為.a 檔案中僅僅包含二進位的代碼,不包含資源檔,如果你需要是資源還要把資源匯入 6.匯入靜態庫中使用的資,運行點擊螢幕輸出內容:
ToolsTest[2276:256084] <UIImage: 0x7fbf7bc25b30>, {202, 76}
這樣使用靜態庫非常麻煩,並且與當前項目的資源混雜在一起,容易丟失
-
當靜態庫中包含一些固定的資源檔時候最好打包一個bundle,方便其他人使用
1. 建立一個檔案夾命名為:resource(此處你可以根據需要隨意命名)
- 把需要的資源拖入當前檔案夾
- 為給檔案夾添加尾碼.bundle
-
修改資源載入路徑,檔案前面添加包路徑
+ (UIImage *) logoOfItcast{ return [UIImage imageNamed:@"resource.bundle/logo_itcast.png"];}+ (UIImage *) logoOfItheima{ return [UIImage imageNamed:@"resource.bundle/logo_itheima.png"];}+ (UIImage *) lufei{ return [UIImage imageNamed:@"resource.bundle/logo_itheima.png"];}
- 編譯,測試, 替換ToolsTest項目中
.a,.h檔案並匯入resource.bundle檔案即可.
-
運行,點擊螢幕,輸出內容:
ToolsTest[2276:256084] <UIImage: 0x7fbf7bc25b30>, {202, 76}
靜態庫的版本
靜態庫的四個版本
1. 真機-Debug版本2. 真機-Release版本3. 模擬器-Debug版本4. 模擬器-Release版本
調試版本(Debug版本) VS 發布版本(Release版本)
- 調試版
- 調試版本會包含完整的符號資訊,以方便調試
- 調試版本不會對代碼進行最佳化
- 發布版
- 發布版本不會包含完整的符號資訊
- 發布版本的執行代碼是進行過最佳化的
- 發布版本的大小會比調試版本的略小
- 在執行速度方面,調試版本會更快些,但不意味著會有顯著的提升
如何產生發布版靜態庫
- 預設情況下產生的版本都是
調試版靜態庫,如何產生發布版的靜態呢?
-
步驟:
- 編輯scheme
-
-
配置運行為發布
-
- 再編譯靜態庫(類比與真機上都要),產生發布版靜態庫
- 發布版真機版 Release-iphoneos
- 發布版模擬器版 Release-iphonesimulator
靜態庫與CPU架構
- 把模擬器調整到iphone5,編譯報錯
- 錯誤
-
- 錯誤原因:匯入的.a檔案,不支援類比iPhone5的CPU架構i386
- CPU架構說明:
1. 模擬器CPU架構: 1. iPhone4s,iPhone5->`i366` 2. iPhone5s以後->`x86_64` 2. 真機CPU架構: 1. iPhone3gs-->iPhone4s : `armv7` 2. iPhone5-->iPhone5c : `armv7s` 3. iPhone5s-->iPhone6plus : `arm64`
- 通過終端命令查看.a檔案所支援的CUP架構
lipo -info 靜態庫.a
- not a fat file : 說明該.a檔案不支援多重架構
- architecture: x86_64 : 說明該.a 支援x86_64架構
- 如何讓產生.a檔案支援i386:
Build Settings -->Build Active Architecture Only-->NO,:
-
- 重新編譯:
- product->clear
- 模擬器下編譯
- 真機下編譯
- 再次查看類比所支援的架構
- 合并靜態庫
- 通過終端命令可以將靜態庫進行合并:
lipo -create 靜態庫1.a 靜態庫2.a -output 新靜態庫的名稱.a
- 查看產生後的靜態庫 :
- 測試產生後的靜態庫
- 把測試專案中原來的的.a檔案替換成為新的.a檔案
- 分別在4s,6s和真機下運行測試專案
製作framework 使用framework製作動態庫
-
使用framework製作動態庫
- 建立一個framework項目,
- 注意:framework項目中不可以包含特殊字元
- 建立一個名稱為
預習01-framework製作編譯,報錯如下
- 刪除原來項目重新建立一個
MakeFrawork項目
- 一個framework預設就有一個與項目同名的主標頭檔,該標頭檔用於包含其他的標頭檔,當使用者使用這個framework的時候,只需要匯入主標頭檔即可
- 建立CZTools的工具類
- 實現一個簡單的類方法
-
讓標頭檔暴露在外部
- 設定支援多種架構(與靜態庫相同)
- 編譯framework(需要模擬器和真機上都進行編譯)
-
測試framework
- 建立測試專案
FrameworkTest
- 匯入
MakeFramework.framework
- 在
ViewController.m中匯入標頭檔
- 格式:
#import <MakeFramework/MakeFramework.h>
-
調用framework中的方法
#import <MakeFramework/MakeFramework.h> @interface ViewController () @end @implementation ViewController - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { int rs = [CZTools sumOfNum1:10 andNum2:20]; NSLog(@"%d",rs); } @end
-
運行測試專案,報錯:
錯誤原因:預設情況下framework是動態庫,使用的時候還需要添加到 embedded binaries (被嵌入的二進位)
- 第一步:target->general->embedded binaries->
+
- 第二步:選擇framework ->
add
在再次運行項目,點擊螢幕列印出 30
注意: 項目中如果使用了自製的動態庫,在Xcode6之前不能被上傳到.AppStore,Xcode6以後可以上傳AppStore
-
使用framework也可以是靜態庫的形式,
- 只需要簡單修改
target -> Bulid Setting-> Mach-O Type -> Statuc Library
- 測試framework的靜態庫,只需要把framework檔案拖入到項目中即可!
-
其實可以framework理解為是.a 檔案與.h檔案的合體,所以在使用上framework比.a檔案更加方便,現在很多第三方架構使用的都是framework的形式.
- 帶有資源的framework與可測試的framework與靜態庫相同,此處不再贅述.
靜態庫和動態庫