iOS創(chuàng)建與使用靜態(tài)庫
在日常項(xiàng)目開發(fā)中,不論是為了兩個(gè)公司項(xiàng)目上的業(yè)務(wù)交流還是為了減少項(xiàng)目的編譯時(shí)間,有的時(shí)候我們會(huì)把項(xiàng)目中的私密內(nèi)容打包成靜態(tài)庫,或者是把項(xiàng)目中變動(dòng)較少一部分打包成靜態(tài)庫以便提高編譯效率,那么下面我們就來學(xué)習(xí)一下"iOS-靜態(tài)庫的創(chuàng)建與使用":
(一)iOS靜態(tài)庫、動(dòng)態(tài)庫與Framework靜態(tài)庫與動(dòng)態(tài)庫的區(qū)別
(1)什么是庫?
庫(Library)直白一點(diǎn)說就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別人使用;(例如: iOS中Objective-C編譯下的.h和.m文件,打包靜態(tài)庫后會(huì)變?yōu)?h和.a文件);
(2)什么是靜態(tài)庫?
①靜態(tài)庫即靜態(tài)鏈接庫(例如: windows下的.lib、Mac和Linux下的.a);
②靜態(tài)庫在編譯的時(shí)候會(huì)被直接拷貝一份,復(fù)制到目標(biāo)程序里并且這段代碼在目標(biāo)程序里就不會(huì)在改變了,我猜這也是該庫叫"靜態(tài)庫"的原因;
③靜態(tài)庫的利弊:
1)利: 靜態(tài)庫在編譯完成之后,庫文件實(shí)際上就沒有作用了,目標(biāo)程序沒有外部依賴,直接就可以運(yùn)行;
2)弊: 弊端靜態(tài)庫會(huì)使用目標(biāo)程序的體積增大;
(3)什么是動(dòng)態(tài)庫?
①動(dòng)態(tài)庫即動(dòng)態(tài)鏈接庫(例如: windows下的.dll、Mac下的.dylib、Linux下的.so);
②與靜態(tài)庫相反,動(dòng)態(tài)庫在編譯時(shí)并不會(huì)被拷貝到目標(biāo)程序中,目標(biāo)程序中只會(huì)存儲(chǔ)指向動(dòng)態(tài)庫的引用,等到程序運(yùn)行時(shí),動(dòng)態(tài)庫才會(huì)被真正加載進(jìn)來;
③動(dòng)態(tài)庫的利弊:
1)利:不需要拷貝到目標(biāo)程序中,不會(huì)影響目標(biāo)程序的體積,而且同一份庫可以被多個(gè)程序使用(因?yàn)檫@個(gè)原因,動(dòng)態(tài)庫也被稱作共享庫);同時(shí),編譯時(shí)才載入的特性,也可以讓我們隨時(shí)對(duì)庫進(jìn)行替換,而不需要重新編譯代碼;
2)弊:動(dòng)態(tài)載入會(huì)帶來一部分性能損失,使用動(dòng)態(tài)庫也會(huì)使得程序依賴于外部環(huán)境;如果環(huán)境缺少動(dòng)態(tài)庫或者庫的版本不正確,就會(huì)導(dǎo)致程序無法運(yùn)行;
(4)什么時(shí)候我們會(huì)用到庫呢?
①某些代碼片段需要給別人使用,但是我們不希望別人看到源碼,就需要以庫的形式進(jìn)行封裝,只暴露出頭文件;
②對(duì)于某些不會(huì)進(jìn)行大的改動(dòng)的代碼,我們想減少編譯的時(shí)間,就可以把它打包成庫,因?yàn)閹焓且呀?jīng)編譯好的二進(jìn)制了,編譯的時(shí)候只需要 Link 一下,不會(huì)浪費(fèi)編譯時(shí)間;
說明:上面提到庫在使用的時(shí)候需要Link,Link 的方式有兩種:靜態(tài)和動(dòng)態(tài),于是便產(chǎn)生了靜態(tài)庫和動(dòng)態(tài)庫("攻城獅"的思維就是這么簡單);
(5)iOS Framework?
①除了上面我們提到iOS的.a和.dylib之外,Mac OS/iOS 平臺(tái)還可以使用 Framework,Framework實(shí)際上是一種打包方式,將庫的二進(jìn)制文件、頭文件和有關(guān)的資源文件打包到一起,方便管理和分發(fā);在 iOS 8 之前,iOS 平臺(tái)不支持使用動(dòng)態(tài) Framework,開發(fā)者可以使用的 Framework 只有蘋果自家的 UIKit.Framework,Foundation.Framework 等等;
②上面這種限制可能是出于安全的考慮,換一個(gè)角度講,因?yàn)?iOS 應(yīng)用都是運(yùn)行在沙盒當(dāng)中,不同的程序之間不能共享代碼,同時(shí)動(dòng)態(tài)下載代碼又是被蘋果明令禁止的,沒辦法發(fā)揮出動(dòng)態(tài)庫的優(yōu)勢(shì),實(shí)際上動(dòng)態(tài)庫也就沒有存在的必要了;
③由于上面提到的限制,開發(fā)者想要在 iOS 平臺(tái)共享代碼,唯一的選擇就是打包成靜態(tài)庫 .a 文件,同時(shí)附上頭文件;但是這樣的打包方式不夠方便,使用時(shí)也比較麻煩,大家還是希望共享代碼都能能像 Framework 一樣,直接扔到工程里就可以用;
④終于在日思夜盼便迎來了iOS對(duì)動(dòng)態(tài)庫的支持:iOS 8/Xcode 6 推出之后,iOS 平臺(tái)添加了動(dòng)態(tài)庫的支持,同時(shí) Xcode 6 也原生自帶了 Framework 支持(動(dòng)態(tài)和靜態(tài)都可以);
⑤但是說道這里博主要告訴一下大家,iOS動(dòng)態(tài)庫且用且珍惜(小心應(yīng)用審核被拒😄😄);
(二)切入主題"iOS靜態(tài)庫的創(chuàng)建":
(1)我們先了解靜態(tài)庫文件的版本(四種):
①真機(jī)-Debug版本; ②真機(jī)-Release版本 ?、勰M器-Debug版本 ?、苣M器-Release版本;
(2)Debug(調(diào)試)版本特點(diǎn):
①含完整的符號(hào)信息,以方便調(diào)試; ?、诓粫?huì)對(duì)代碼進(jìn)行優(yōu)化;
(3)Release(發(fā)布)版本特點(diǎn):
①不會(huì)包含完整的符號(hào)信息; ②執(zhí)行代碼是進(jìn)行過優(yōu)化的; ?、鄞笮?huì)比Debug版本的略小 ?、茉趫?zhí)行速度方面,Release版本會(huì)快一些;
所以我們一般開發(fā)中都打包Release(發(fā)布)版本使用;
(4)再來了解一下iPhone設(shè)備CPU的架構(gòu)簡介:
①模擬器:(4s~5: i386) (5s~6splus: x86_64)
②真 機(jī): (3gs~4s: armv7) (5~5c: armv7s) (5s~6splus: arm64)[說明: 靜態(tài)庫只要支持了armv7,就可以跑在armv7s的架構(gòu)上];
(三)制作靜態(tài)庫-Debug版本:
(1)創(chuàng)建Cocoa Touch Static Library,新建項(xiàng)目選擇iOS ->Framework&Library ->Cocoa Touch Static Library,如圖1:

(2)點(diǎn)擊Next給工程命名如"Library"點(diǎn)擊Next,Xcode自動(dòng)為我們創(chuàng)建了Library.h/.m文件以及相對(duì)應(yīng)的目錄結(jié)構(gòu),如圖2所示:

(3)接下來我們?cè)诠こ痰?h和.m里面編寫功能實(shí)現(xiàn)的代碼(重在靜態(tài)庫的創(chuàng)建, 代碼粗略請(qǐng)大家無視😄😄):
"Library.h"
/** 十六進(jìn)制轉(zhuǎn)二進(jìn)制 */
+ (NSString *)getBinaryByhex:(NSString *)hex;
"Library.m"
+ (NSString *)getBinaryByhex:(NSString *)hex {
NSMutableDictionary *hexDic = [[NSMutableDictionary alloc] init];
hexDic = [[NSMutableDictionary alloc] initWithCapacity:16];
[hexDic setObject:@"0000" forKey:@"0"];
[hexDic setObject:@"0001" forKey:@"1"];
[hexDic setObject:@"0010" forKey:@"2"];
[hexDic setObject:@"0011" forKey:@"3"];
[hexDic setObject:@"0100" forKey:@"4"];
[hexDic setObject:@"0101" forKey:@"5"];
[hexDic setObject:@"0110" forKey:@"6"];
[hexDic setObject:@"0111" forKey:@"7"];
[hexDic setObject:@"1000" forKey:@"8"];
[hexDic setObject:@"1001" forKey:@"9"];
[hexDic setObject:@"1010" forKey:@"A"];
[hexDic setObject:@"1011" forKey:@"B"];
[hexDic setObject:@"1100" forKey:@"C"];
[hexDic setObject:@"1101" forKey:@"D"];
[hexDic setObject:@"1110" forKey:@"E"];
[hexDic setObject:@"1111" forKey:@"F"];
NSString *binaryString=[[NSMutableString alloc] init];
for (int i=0; i<[hex length]; i++) {
NSRange rage;
rage.length = 1;
rage.location = i;
NSString *key = [hex substringWithRange:rage];
binaryString = [NSString stringWithFormat:@"%@%@",binaryString,[NSString stringWithFormat:@"%@",[hexDic objectForKey:key]]];
}
return binaryString;
}
(4)編譯項(xiàng)目生成對(duì)應(yīng)的靜態(tài)庫.a文件(在這里注意一下細(xì)節(jié)):
①在工程編譯(Command+B)之前"標(biāo)號(hào)為②的框框中l(wèi)ibLibrary.a"為紅色(編譯之后為黑色, 紅色表示一個(gè)虛擬的文件工程中找不到它),如圖3所示:

②編譯的過程中我們要選擇"模擬器編譯"和"真機(jī)編譯",如圖4圖5所示:


(5)右擊工程目錄下.a文件,查看編譯之后的靜態(tài)庫文件如圖6所示, 其中文件Debug-iphoneos里面包含iPhone真機(jī)所需要的libLibrary.a靜態(tài)庫文件,文件Debug-iphonesimulator里面包含的時(shí)iPhone模擬器所需要的libLibrary.a靜態(tài)庫文件,如圖7所示;


(6)分別查看打包好的模擬器與真機(jī)的靜態(tài)庫所支持的cpu架構(gòu):
在上面我們介紹了iPhone設(shè)備CPU的架構(gòu),在這里我們就來查看我們所打包的靜態(tài)庫是否符合iPhone設(shè)備包含的架構(gòu)標(biāo)準(zhǔn)(提示: 如果不符合某些架構(gòu)的標(biāo)準(zhǔn),靜態(tài)庫運(yùn)行到不同機(jī)型上回報(bào)錯(cuò)誤),打開終端查看靜態(tài)庫的架構(gòu)如圖8所示:

我們找到原因如圖9所示,下面Debug:Yes表示只編譯選中模擬器對(duì)應(yīng)的架構(gòu),No則為編譯所有模擬器支持的cup架構(gòu)(Debug的Yes狀態(tài)改為No即可);

再一次Command+B 編譯重復(fù)上面第(4)步的小步驟,就OK了,😄😄...
(7)合并靜態(tài)庫:
①為什么要合并靜態(tài)庫呢?
因?yàn)檎鏅C(jī)和模擬器的靜態(tài)庫,是不一樣的,不能同時(shí)適用在真機(jī)和模擬器上,但要滿足這要求的話,要對(duì)編譯好的兩個(gè)靜態(tài)庫進(jìn)行合并在使用;
②合并靜態(tài)庫的利弊?
1)利:開發(fā)過程中既可以在真機(jī)上調(diào)試,也可以在模擬器上調(diào)試;
2)弊:如果靜態(tài)庫太大,合并打包后,會(huì)非常大,因此很多第三方的靜態(tài)庫的.a是區(qū)分版本的;
③打開終端合并靜態(tài)庫(終于快成功了😄😄...)如圖10所示:

其中完整的命令是:
(8)靜態(tài)庫的使用:
將合并好的靜態(tài)庫文件(.a)和頭文件(.h)添加到工程里面,調(diào)用靜態(tài)庫,結(jié)果如下(代碼粗略請(qǐng)大家無視...):
"ViewController.h"
@interface ViewController : UIViewController
@end
"ViewController.m"
#import "ViewController.h"
#import "Library.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 十六進(jìn)制轉(zhuǎn)二進(jìn)制
NSLog(@"十六進(jìn)制轉(zhuǎn)二進(jìn)制: %@", [Library getBinaryByhex:@"F"]);
}
日志打印輸入結(jié)果是:
靜態(tài)庫的使用[1006:40288] 十六進(jìn)制轉(zhuǎn)二進(jìn)制: 1111
(四)制作靜態(tài)庫-Release版本:
跟Debug版步驟一樣,只不過在編譯時(shí),改下面的選項(xiàng)即可如圖12所示:

這時(shí)不管是真機(jī)還是模擬器都可以編譯通過,正常運(yùn)行;而使用者只能通過頭文件知道我們提供的借口,卻不知道實(shí)現(xiàn)文件中實(shí)現(xiàn)的細(xì)節(jié),這有效地隱藏了自己的核心技術(shù)和機(jī)密內(nèi)容;
以上就是我對(duì)iOS靜態(tài)庫的理解與解釋,希望大家相互補(bǔ)充相互學(xué)習(xí)。
- 解決ios模擬器不能彈出鍵盤問題的方法
- iOS應(yīng)用開發(fā)中監(jiān)聽鍵盤事件的代碼實(shí)例小結(jié)
- 總結(jié)IOS關(guān)閉鍵盤/退出鍵盤的五種方式
- 查看iOS Crash logs的方法
- iOS10適配之權(quán)限Crash問題的完美解決方案
- iOS Crash文件分析方法匯總
- IOS開發(fā)代碼分享之獲取啟動(dòng)畫面圖片的string
- IOS實(shí)戰(zhàn)之自定義轉(zhuǎn)場(chǎng)動(dòng)畫詳解
- IOS 打包靜態(tài)庫詳細(xì)介紹
- iOS開發(fā)筆記之鍵盤、靜態(tài)庫、動(dòng)畫和Crash定位
相關(guān)文章
iOS實(shí)現(xiàn)錄音轉(zhuǎn)碼MP3及轉(zhuǎn)碼BASE64上傳示例
本篇文章主要介紹了iOS實(shí)現(xiàn)錄音轉(zhuǎn)碼MP3及轉(zhuǎn)碼BASE64上傳示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
iOS實(shí)現(xiàn)文字水平無間斷滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)文字水平無間斷滾動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
Flutter之PageView頁面緩存與KeepAlive
這篇文章主要為大家介紹了Flutter之PageView頁面緩存與KeepAlive示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
iOS仿抖音視頻加載動(dòng)畫效果的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于iOS視頻加載動(dòng)畫效果的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
IOS設(shè)置QQ小紅點(diǎn)消除的方法(一鍵退朝)
這篇文章主要介紹了IOS設(shè)置QQ小紅點(diǎn)消除的方法(一鍵退朝),對(duì)ios設(shè)置小紅點(diǎn)消除相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01

