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

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

最近在做一個(gè)小項(xiàng)目,需要給客戶一個(gè)demo測(cè)試,有一部分核心代碼暫時(shí)不想讓客戶知道,就想到了打包成framework或.a庫(kù)。庫(kù)有兩種:

  • 靜態(tài)庫(kù):.a和.framework
  • 動(dòng)態(tài)庫(kù):.tbd和.framework

靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別

  • .a文件肯定是靜態(tài)庫(kù),. tbd肯定是動(dòng)態(tài)庫(kù),.framework可能是靜態(tài)庫(kù)也可能是動(dòng)態(tài)庫(kù)
  • 靜態(tài)庫(kù)在鏈接時(shí),會(huì)被完整的復(fù)制到可執(zhí)行文件中,如果多個(gè)App都使用了同一個(gè)靜態(tài)庫(kù),那么每個(gè)App都會(huì)拷貝一份,缺點(diǎn)是浪費(fèi)內(nè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)存。類似于使用變量的內(nèi)存地址一樣,使用的是同一個(gè)變量;
  • 在iOS8.0以后蘋(píng)果開(kāi)放了動(dòng)態(tài)加載. tbd的接口,用于掛載. tbd動(dòng)態(tài)庫(kù),項(xiàng)目中也可以使用了自己定義的動(dòng)態(tài)庫(kù)。

總結(jié):
靜態(tài)庫(kù):
1.編譯時(shí)將程序放進(jìn)進(jìn)可執(zhí)行程序
2.會(huì)產(chǎn)生多分副本
3.不依賴程序運(yùn)行
動(dòng)態(tài)庫(kù):
1.程序運(yùn)行時(shí),加載時(shí)才去動(dòng)態(tài)庫(kù)找函數(shù)
2.多進(jìn)程共享
3.依賴程序運(yùn)行

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

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

使用動(dòng)態(tài)庫(kù)的好處

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

靜態(tài)庫(kù)的使用場(chǎng)景

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

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

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

真機(jī)

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

沒(méi)有armv64

下面言歸正傳,做點(diǎn)正事

.a靜態(tài)庫(kù)

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

a1.jpeg

完成

a2.jpeg

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

a3.jpeg
a4.jpeg

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

a5.jpeg
a6.jpeg

3.選擇需要公開(kāi)的頭文件

  • 添加頭文件
a7.gif

4.修改配置

  • Build Active Architecture Only修改為NO,否則生成的靜態(tài)庫(kù)就只支持當(dāng)前選擇設(shè)備的架構(gòu)。
a8.jpeg
  • iOS Deployment Target ,靜態(tài)庫(kù)需要支持版本
a9.jpeg
  • Mach-O Type更改成Static Library,.a默認(rèn)就是Static Library,這一步可以省略
a10.jpeg

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

a11.gif

可以看到真機(jī)與模擬器都生成了.a。里面都有有我選擇公開(kāi)的頭文件
這個(gè)時(shí)候,可以用命令lipo -info 靜態(tài)庫(kù)名字來(lái)看下,支持的iOS的CPU框架

a12.gif
  • Debug-iphoneos里面支持armv7、arm64,屬于真機(jī),用到模擬器就會(huì)報(bào)錯(cuò)
  • Debug-iphonesimulator里面支持i386、x86_64,屬于模擬器,用到真機(jī)會(huì)報(bào)錯(cuò)

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

a13.gif

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

a14.gif

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

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

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

a15.jpeg

.framework靜態(tài)庫(kù)

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

  • 創(chuàng)建完成后的framework.hInfn.plist不要?jiǎng)h除(創(chuàng)建framework的時(shí)候命名不要用framework命名,否則在使用這個(gè)framework的時(shí)候會(huì)報(bào)錯(cuò))
framework1.png

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

framework2.jpeg
framework3.jpeg
注意事項(xiàng):
  • 如果打包的文件中有設(shè)置圖片的地方,如果還是通過(guò)[UIImage imageNamed:]的方式設(shè)置,圖片可能不會(huì)顯示。
  • 圖片最好單獨(dú)打包一個(gè)bundle,這個(gè)時(shí)候設(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.選擇要公開(kāi)的頭文件
這里主要是讓使用者知道有哪些方法和頭文件可以使用

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

注意。要在這個(gè)文件中引入需要公開(kāi)的頭文件

framework6.jpeg

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

4.修改配置

  • Build Active Architecture Only修改為NO,否則生成的靜態(tài)庫(kù)就只支持當(dāng)前選擇設(shè)備的架構(gòu)。

    framework7.jpeg
  • Mach-O Type,因?yàn)閯?dòng)態(tài)庫(kù)也可以是以framework形式存在,所以需要設(shè)置,否則默認(rèn)打出來(lái)的是動(dòng)態(tài)庫(kù)。
    靜態(tài)庫(kù)Static Library(默認(rèn)為Dynamic Library

framework8.jpeg
  • iOS Deployment Target ,靜態(tài)庫(kù)需要支持版本
framework9.jpeg

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

framework10.gif

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

framework11.gif
  • Debug-iphoneos里面支持armv7、arm64,屬于真機(jī),用到模擬器就會(huì)報(bào)錯(cuò)
  • Debug-iphonesimulator里面支持i386、x86_64,屬于模擬器,用到真機(jī)會(huì)報(bào)錯(cuò)

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

framework12.gif

將合成的二進(jìn)制文件拖進(jìn)任何一個(gè)framework,替換掉原來(lái)的,然后把這個(gè)新的framework拖進(jìn)項(xiàng)目就可以使用了

使用framework靜態(tài)庫(kù)

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

framework13.jpeg

如果靜態(tài)庫(kù)中有Category類,就要在使用靜態(tài)庫(kù)項(xiàng)目的配置中找到主工程的 target --Build Setting--Linking--更改其 Other Linker Flags為:-ObjC-all_load 即可。
如果創(chuàng)建的framework類中使用了.tbd,則項(xiàng)目中也要導(dǎo)入.tbd動(dòng)態(tài)庫(kù)

參考文章:
iOS中,Framework和.a的打包及使用
靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別以及framework的使用
C語(yǔ)言靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別的深入分析

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

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

  • 最近在做一個(gè)小項(xiàng)目,需要給客戶一個(gè)demo測(cè)試,有一部分核心代碼暫時(shí)不想讓客戶知道,就想到了打包成framewor...
    carpond閱讀 14,129評(píng)論 19 62
  • 靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)的區(qū)別 首先來(lái)看什么是庫(kù),庫(kù)(Library)說(shuō)白了就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別...
    吃瓜群眾呀閱讀 12,313評(píng)論 3 42
  • 從七月開(kāi)始恢復(fù)每周的閱讀,選擇精力管理也是合適的開(kāi)始。總覺(jué)得自己時(shí)間不夠用,拖延癥又日漸嚴(yán)重,看過(guò)一些時(shí)間管理的書(shū)...
    鈴蘭小語(yǔ)閱讀 889評(píng)論 2 0
  • 忙碌的時(shí)候 會(huì)忘記表達(dá) 最近 由于忙碌 我不再讀書(shū) 不再寫(xiě)字 只是專注的忙碌 忙碌些應(yīng)該忙碌的事情 ...
    陳列達(dá)杰閱讀 305評(píng)論 0 0
  • 這本書(shū)估計(jì)還剩不到100頁(yè)了,今天下班回去就可以看完,這個(gè)系列明天再寫(xiě)一篇就結(jié)束了。 昨天下班就去踢球,從7點(diǎn)30...
    聞舒閱讀 337評(píng)論 0 0

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