iOS中,Framework和 a的打包及使用

Oranges發表於2017-12-13

最近在做一個小專案,需要給客戶一個demo測試,有一部分核心程式碼暫時不想讓客戶知道,就想到了打包成framework或.a庫。庫有兩種:

  • 靜態庫:.a和.framework
  • 動態庫:.tbd和.framework

靜態庫和動態庫的區別

  • .a檔案肯定是靜態庫,. tbd肯定是動態庫,.framework可能是靜態庫也可能是動態庫
  • 靜態庫在連結時,會被完整的複製到可執行檔案中,如果多個App都使用了同一個靜態庫,那麼每個App都會拷貝一份,缺點是浪費記憶體。類似於定義一個基本變數,使用該基本變數是是新複製了一份資料,而不是原來定義的;
  • 動態庫不會複製,只有一份,程式執行時動態載入到記憶體中,系統只會載入一次,多個程式共用一份,節約了記憶體。類似於使用變數的記憶體地址一樣,使用的是同一個變數;
  • 但是專案中如果使用了自己定義的動態庫,蘋果是不允許上架的,在iOS8.0以後蘋果開放了動態載入. tbd的介面,用於掛載. tbd動態庫

使用靜態庫的好處

  • 模組化,分工合作
  • 避免少量改動經常導致大量的重複編譯連線
  • 也可以重用,注意不是共享使用

使用動態庫的好處

  • 使用動態庫,可以將最終可執行檔案體積縮小
  • 使用動態庫,多個應用程式共享記憶體中得同一份庫檔案,節省資源
  • 使用動態庫,可以不重新編譯連線可執行程式的前提下,更新動態庫檔案達到更新應用程式的目的。

靜態庫的使用場景

  • 保護自己的核心程式碼,自己不想別人看到的部分
  • 將MRC的專案打包成靜態庫,可以在ARC下直接使用,不需要在轉換

iOS裝置的CPU架構 模擬器

  • 4S-5:i386
  • 5s-7P:x86_64

真機

  • armv6:iPhone - iPhone3G
  • armv7:iPhone 3Gs,4,4S,iPad,iPad2
  • armv7s: iPhone 5、iPhone 5c <靜態庫只要支援了armv7,就可以在armv7s的架構上執行>
  • arm64:iPhone 5s、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPad Air、iPad Air2、iPad mini2、iPad mini3

沒有armv64

下面言歸正傳,做點正事

.a靜態庫

1.建立一個新的工程,選擇下面這個模板:

圖1.png
完成

圖2.png

2.我這裡就在Test操作了(親,你打包.a的時候,可以刪除預設檔案,拉入自己想加入的任何檔案)

圖3.png

圖4.png

下面在建立一個Person類

圖5.png

圖6.png

3.選擇需要公開的標頭檔案

  • 新增標頭檔案

新增標頭檔案.gif

4.修改配置

  • Build Active Architecture Only修改為NO,否則生成的靜態庫就只支援當前選擇裝置的架構。

圖7.png

  • iOS Deployment Target ,靜態庫需要支援版本

圖8.png

  • ach-O Type更改成Static Library,.a預設就是Static Library,這一步可以省略

圖9.png

5.編譯 選擇Generic iOS Device任意一個模擬器各編譯一次,完成後,在工程的Products資料夾下的.a檔案從紅色程式設計了黑色。編譯成功,然後Show in Finder

編譯.gif

可以看到真機與模擬器都生成了.a。裡面都有有我選擇公開的標頭檔案 這個時候,可以用命令lipo -info 靜態庫名字來看下,支援的iOS的CPU框架

支援架構.gif

  • Debug-iphoneos裡面支援armv7、arm64,屬於真機,用到模擬器就會報錯
  • Debug-iphonesimulator裡面支援i386、x86_64,屬於模擬器,用到真機會報錯

6.合併靜態庫-讓模擬器和真機使用一個靜態庫 命令如下: lipo -create第一個.a檔案的絕對路徑 第二個.a檔案的絕對路徑 -output 最終的.a檔案路徑

合成靜態庫.gif

這個生成的libTest.a,就是支援真機和模擬器的靜態庫了。建立一個資料夾,把.a和標頭檔案拖進去,這個資料夾就是我們所需要的。

完成.gif

為了開發方便,我們可以使用生成的通用靜態庫,但是上線的時候只匯入真機的,這樣工程的體積也會小一些。

使用.a靜態庫

新建一個工程,把我們的靜態庫拖進去,匯入標頭檔案。

圖10.png

###.framework靜態庫 1.Xcode建立一個新工程,需要選擇這個Cocoa Touch Framework這個模板

  • 建立完成後的framework.hInfn.plist不要刪除(建立framework的時候命名不要用framework命名,否則在使用這個framework的時候會報錯)

圖11.png

2.建立Person,也是輸入名字和年齡,和.a一樣

圖12.png

圖13.png

#####注意事項:

  • 如果打包的檔案中有設定圖片的地方,如果還是通過[UIImage imageNamed:]的方式設定,圖片可能不會顯示。
  • 圖片最好單獨打包一個bundle,這個時候設定圖片的方式為:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//拿到路徑
NSString *path = [[NSBundle mainBundle] pathForResource:@"bundle" ofType:@"bundle"];
//設定圖片
UIImage *image = [UIImage imageNamed:@"delete" inBundle:[NSBundle bundleWithPath:path] compatibleWithTraitCollection:nil];
            
 [button setImage:image forState:UIControlStateNormal];
複製程式碼

3.選擇要公開的標頭檔案 這裡主要是讓使用者知道有哪些方法和標頭檔案可以使用

  • 第一種新增標頭檔案的方式,把需要公開的標頭檔案新增到public裡面

圖14.png

  • 第二種新增標頭檔案的方式。在右側的選擇中,選擇Public

第二種方式新增標頭檔案.gif

注意。要在這個檔案中引入需要公開的標頭檔案

圖15.png

這裡有一個注意點,公開的標頭檔案中,#import的其他類也要公開,新增到public中,如果不想公開,就在標頭檔案用用@class的方式,在對應的.m中用#import方式

4.修改配置

  • Build Active Architecture Only修改為NO,否則生成的靜態庫就只支援當前選擇裝置的架構。

    圖16.png

  • Mach-O格式,因為動態庫也可以是以framework形式存在,所以需要設定,否則預設打出來的是動態庫。 靜態庫Static Library(預設為Dynamic Library

圖17.png

  • 支援版本

圖18.png

5.編譯 選擇Generic iOS Device任意一個模擬器各編譯一次,完成後,在工程的Products資料夾下的.a檔案從紅色程式設計了黑色。編譯成功,然後Show in Finder

生成framework.gif

可以看到真機與模擬器都生成了.framework。裡面都有我們選擇公開的標頭檔案 這個時候,可以用命令lipo -info framework靜態庫檔案下二進位制檔案的名字來看下,支援的iOS的CPU框架

支援框架.gif

  • Debug-iphoneos裡面支援armv7、arm64,屬於真機,用到模擬器就會報錯
  • Debug-iphonesimulator裡面支援i386、x86_64,屬於模擬器,用到真機會報錯

6.合併靜態庫-讓模擬器和真機使用一個靜態庫 命令如下: lipo -create第一個framework檔案下二進位制檔案的絕對路徑 第二個framework檔案下二進位制檔案的絕對路徑 -output 最終的二進位制檔案路徑

新的framework.gif

將合成的二進位制檔案拖進任何一個framework,替換掉原來的,然後把這個新的framework拖進專案就可以使用了

使用framework靜態庫

新建一個工程,把我們的靜態庫拖進去,匯入標頭檔案。然後呼叫Person中的方法。

圖19.png

如果靜態庫中有Category類,就要在使用靜態庫專案的配置中新增-ObjC或者-all_load 如果建立的framework類中使用了.tbd,則專案中也要匯入.tbd動態庫

註釋:部分名詞摘自網路。雖然說,學到的都是我們的,但是也不要忘記他人。

如果有錯誤的地方歡迎指出,一起學習,一起進步。 如果有不懂的地方,請留言,或者加QQ810646506 如果喜歡給個贊哈

相關文章