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

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

  • 靜態(tài)庫:.a和.framework
  • 動態(tài)庫:.tbd和.framework

靜態(tài)庫和動態(tài)庫的區(qū)別

  • .a文件肯定是靜態(tài)庫,. tbd肯定是動態(tài)庫,.framework可能是靜態(tài)庫也可能是動態(tài)庫
  • 靜態(tài)庫在鏈接時,會被完整的復(fù)制到可執(zhí)行文件中,如果多個App都使用了同一個靜態(tài)庫,那么每個App都會拷貝一份,缺點是浪費內(nèi)存。類似于定義一個基本變量,使用該基本變量是是新復(fù)制了一份數(shù)據(jù),而不是原來定義的;
  • 動態(tài)庫不會復(fù)制,只有一份,程序運行時動態(tài)加載到內(nèi)存中,系統(tǒng)只會加載一次,多個程序共用一份,節(jié)約了內(nèi)存。類似于使用變量的內(nèi)存地址一樣,使用的是同一個變量;
  • 在iOS8.0以后蘋果開放了動態(tài)加載. tbd的接口,用于掛載. tbd動態(tài)庫,項目中也可以使用了自己定義的動態(tài)庫。

使用靜態(tài)庫的好處

  • 模塊化,分工合作
  • 避免少量改動經(jīng)常導(dǎo)致大量的重復(fù)編譯連接
  • 也可以重用,注意不是共享使用

使用動態(tài)庫的好處

  • 使用動態(tài)庫,可以將最終可執(zhí)行文件體積縮小
  • 使用動態(tài)庫,多個應(yīng)用程序共享內(nèi)存中得同一份庫文件,節(jié)省資源
  • 使用動態(tài)庫,可以不重新編譯連接可執(zhí)行程序的前提下,更新動態(tài)庫文件達到更新應(yīng)用程序的目的。

靜態(tài)庫的使用場景

  • 保護自己的核心代碼,自己不想別人看到的部分
  • 將MRC的項目打包成靜態(tài)庫,可以在ARC下直接使用,不需要在轉(zhuǎn)換

iOS設(shè)備的CPU架構(gòu)
模擬器

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

真機

  • armv6:iPhone - iPhone3G
  • armv7:iPhone 3Gs,4,4S,iPad,iPad2
  • armv7s: iPhone 5、iPhone 5c <靜態(tài)庫只要支持了armv7,就可以在armv7s的架構(gòu)上運行>
  • arm64:iPhone 5s、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPad Air、iPad Air2、iPad mini2、iPad mini3

沒有armv64

下面言歸正傳,做點正事

.a靜態(tài)庫

1.創(chuàng)建一個新的工程,選擇下面這個模板:

圖1.png

完成

圖2.png

2.我這里就在Test操作了(親,你打包.a的時候,可以刪除默認文件,拉入自己想加入的任何文件)

圖3.png
圖4.png

下面在創(chuàng)建一個Person類

圖5.png
圖6.png

3.選擇需要公開的頭文件

  • 添加頭文件
添加頭文件.gif

4.修改配置

  • Build Active Architecture Only修改為NO,否則生成的靜態(tài)庫就只支持當前選擇設(shè)備的架構(gòu)。
圖7.png
  • iOS Deployment Target ,靜態(tài)庫需要支持版本
圖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 靜態(tài)庫名字來看下,支持的iOS的CPU框架

支持架構(gòu).gif
  • Debug-iphoneos里面支持armv7、arm64,屬于真機,用到模擬器就會報錯
  • Debug-iphonesimulator里面支持i386、x86_64,屬于模擬器,用到真機會報錯

6.合并靜態(tài)庫-讓模擬器和真機使用一個靜態(tài)庫
命令如下:
lipo -create第一個.a文件的絕對路徑 第二個.a文件的絕對路徑 -output 最終的.a文件路徑

合成靜態(tài)庫.gif

這個生成的libTest.a,就是支持真機和模擬器的靜態(tài)庫了。創(chuàng)建一個文件夾,把.a和頭文件拖進去,這個文件夾就是我們所需要的。

完成.gif

為了開發(fā)方便,我們可以使用生成的通用靜態(tài)庫,但是上線的時候只導(dǎo)入真機的,這樣工程的體積也會小一些。

使用.a靜態(tài)庫

新建一個工程,把我們的靜態(tài)庫拖進去,導(dǎo)入頭文件。

圖10.png

.framework靜態(tài)庫

1.Xcode創(chuàng)建一個新工程,需要選擇這個Cocoa Touch Framework這個模板

  • 創(chuàng)建完成后的framework.hInfn.plist不要刪除(創(chuàng)建framework的時候命名不要用framework命名,否則在使用這個framework的時候會報錯)
圖11.png

2.創(chuàng)建Person,也是輸入名字和年齡,和.a一樣

圖12.png
圖13.png
注意事項:
  • 如果打包的文件中有設(shè)置圖片的地方,如果還是通過[UIImage imageNamed:]的方式設(shè)置,圖片可能不會顯示。
  • 圖片最好單獨打包一個bundle,這個時候設(shè)置圖片的方式為:
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
//拿到路徑
NSString *path = [[NSBundle mainBundle] pathForResource:@"bundle" ofType:@"bundle"];
//設(shè)置圖片
UIImage *image = [UIImage imageNamed:@"delete" inBundle:[NSBundle bundleWithPath:path] compatibleWithTraitCollection:nil];
            
 [button setImage:image forState:UIControlStateNormal];

3.選擇要公開的頭文件
這里主要是讓使用者知道有哪些方法和頭文件可以使用

  • 第一種添加頭文件的方式,把需要公開的頭文件添加到public里面
圖14.png
  • 第二種添加頭文件的方式。在右側(cè)的選擇中,選擇Public
第二種方式添加頭文件.gif

注意。要在這個文件中引入需要公開的頭文件

圖15.png

這里有一個注意點,公開的頭文件中,#import的其他類也要公開,添加到public中,如果不想公開,就在頭文件用用@class的方式,在對應(yīng)的.m中用#import方式

4.修改配置

  • Build Active Architecture Only修改為NO,否則生成的靜態(tài)庫就只支持當前選擇設(shè)備的架構(gòu)。
    圖16.png
  • Mach-O格式,因為動態(tài)庫也可以是以framework形式存在,所以需要設(shè)置,否則默認打出來的是動態(tài)庫。
    靜態(tài)庫Static Library(默認為Dynamic Library
圖17.png
  • 支持版本
圖18.png

5.編譯
選擇Generic iOS Device任意一個模擬器各編譯一次,完成后,在工程的Products文件夾下的.a文件從紅色編程了黑色。編譯成功,然后Show in Finder

生成framework.gif

可以看到真機與模擬器都生成了.framework。里面都有我們選擇公開的頭文件
這個時候,可以用命令lipo -info framework靜態(tài)庫文件下二進制文件的名字來看下,支持的iOS的CPU框架

支持框架.gif
  • Debug-iphoneos里面支持armv7、arm64,屬于真機,用到模擬器就會報錯
  • Debug-iphonesimulator里面支持i386、x86_64,屬于模擬器,用到真機會報錯

6.合并靜態(tài)庫-讓模擬器和真機使用一個靜態(tài)庫
命令如下:
lipo -create第一個framework文件下二進制文件的絕對路徑 第二個framework文件下二進制文件的絕對路徑 -output 最終的二進制文件路徑

新的framework.gif

將合成的二進制文件拖進任何一個framework,替換掉原來的,然后把這個新的framework拖進項目就可以使用了

使用framework靜態(tài)庫

新建一個工程,把我們的靜態(tài)庫拖進去,導(dǎo)入頭文件。然后調(diào)用Person中的方法。

圖19.png

如果靜態(tài)庫中有Category類,就要在使用靜態(tài)庫項目的配置中添加-ObjC或者-all_load
如果創(chuàng)建的framework類中使用了.tbd,則項目中也要導(dǎo)入.tbd動態(tài)庫

注釋:部分名詞摘自網(wǎng)絡(luò)。雖然說,學到的都是我們的,但是也不要忘記他人。

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容