iOS創(chuàng)建與使用靜態(tài)庫
在日常項(xiàng)目開發(fā)中,不論是為了兩個公司項(xiàng)目上的業(yè)務(wù)交流還是為了減少項(xiàng)目的編譯時(shí)間,有的時(shí)候我們會把項(xiàng)目中的私密內(nèi)容打包成靜態(tài)庫,或者是把項(xiàng)目中變動較少一部分打包成靜態(tài)庫以便提高編譯效率,那么下面我們就來學(xué)習(xí)一下"iOS-靜態(tài)庫的創(chuàng)建與使用":
(一)iOS靜態(tài)庫、動態(tài)庫與Framework靜態(tài)庫與動態(tài)庫的區(qū)別
(1)什么是庫?
庫(Library)直白一點(diǎn)說就是一段編譯好的二進(jìn)制代碼,加上頭文件就可以供別人使用;(例如: iOS中Objective-C編譯下的.h和.m文件,打包靜態(tài)庫后會變?yōu)?h和.a文件);
(2)什么是靜態(tài)庫?
①靜態(tài)庫即靜態(tài)鏈接庫(例如: windows下的.lib、Mac和Linux下的.a);
②靜態(tài)庫在編譯的時(shí)候會被直接拷貝一份,復(fù)制到目標(biāo)程序里并且這段代碼在目標(biāo)程序里就不會在改變了,我猜這也是該庫叫"靜態(tài)庫"的原因;
③靜態(tài)庫的利弊:
1)利: 靜態(tài)庫在編譯完成之后,庫文件實(shí)際上就沒有作用了,目標(biāo)程序沒有外部依賴,直接就可以運(yùn)行;
2)弊: 弊端靜態(tài)庫會使用目標(biāo)程序的體積增大;
(3)什么是動態(tài)庫?
①動態(tài)庫即動態(tài)鏈接庫(例如: windows下的.dll、Mac下的.dylib、Linux下的.so);
②與靜態(tài)庫相反,動態(tài)庫在編譯時(shí)并不會被拷貝到目標(biāo)程序中,目標(biāo)程序中只會存儲指向動態(tài)庫的引用,等到程序運(yùn)行時(shí),動態(tài)庫才會被真正加載進(jìn)來;
③動態(tài)庫的利弊:
1)利:不需要拷貝到目標(biāo)程序中,不會影響目標(biāo)程序的體積,而且同一份庫可以被多個程序使用(因?yàn)檫@個原因,動態(tài)庫也被稱作共享庫);同時(shí),編譯時(shí)才載入的特性,也可以讓我們隨時(shí)對庫進(jìn)行替換,而不需要重新編譯代碼;
2)弊:動態(tài)載入會帶來一部分性能損失,使用動態(tài)庫也會使得程序依賴于外部環(huán)境;如果環(huán)境缺少動態(tài)庫或者庫的版本不正確,就會導(dǎo)致程序無法運(yùn)行;
(4)什么時(shí)候我們會用到庫呢?
①某些代碼片段需要給別人使用,但是我們不希望別人看到源碼,就需要以庫的形式進(jìn)行封裝,只暴露出頭文件;
②對于某些不會進(jìn)行大的改動的代碼,我們想減少編譯的時(shí)間,就可以把它打包成庫,因?yàn)閹焓且呀?jīng)編譯好的二進(jìn)制了,編譯的時(shí)候只需要 Link 一下,不會浪費(fèi)編譯時(shí)間;
說明:上面提到庫在使用的時(shí)候需要Link,Link 的方式有兩種:靜態(tài)和動態(tài),于是便產(chǎn)生了靜態(tài)庫和動態(tài)庫("攻城獅"的思維就是這么簡單);
(5)iOS Framework?
①除了上面我們提到iOS的.a和.dylib之外,Mac OS/iOS 平臺還可以使用 Framework,Framework實(shí)際上是一種打包方式,將庫的二進(jìn)制文件、頭文件和有關(guān)的資源文件打包到一起,方便管理和分發(fā);在 iOS 8 之前,iOS 平臺不支持使用動態(tài) Framework,開發(fā)者可以使用的 Framework 只有蘋果自家的 UIKit.Framework,Foundation.Framework 等等;
②上面這種限制可能是出于安全的考慮,換一個角度講,因?yàn)?iOS 應(yīng)用都是運(yùn)行在沙盒當(dāng)中,不同的程序之間不能共享代碼,同時(shí)動態(tài)下載代碼又是被蘋果明令禁止的,沒辦法發(fā)揮出動態(tài)庫的優(yōu)勢,實(shí)際上動態(tài)庫也就沒有存在的必要了;
③由于上面提到的限制,開發(fā)者想要在 iOS 平臺共享代碼,唯一的選擇就是打包成靜態(tài)庫 .a 文件,同時(shí)附上頭文件;但是這樣的打包方式不夠方便,使用時(shí)也比較麻煩,大家還是希望共享代碼都能能像 Framework 一樣,直接扔到工程里就可以用;
④終于在日思夜盼便迎來了iOS對動態(tài)庫的支持:iOS 8/Xcode 6 推出之后,iOS 平臺添加了動態(tài)庫的支持,同時(shí) Xcode 6 也原生自帶了 Framework 支持(動態(tài)和靜態(tài)都可以);
⑤但是說道這里博主要告訴一下大家,iOS動態(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):
①含完整的符號信息,以方便調(diào)試; ②不會對代碼進(jìn)行優(yōu)化;
(3)Release(發(fā)布)版本特點(diǎn):
①不會包含完整的符號信息; ?、趫?zhí)行代碼是進(jìn)行過優(yōu)化的; ?、鄞笮菵ebug版本的略小 ?、茉趫?zhí)行速度方面,Release版本會快一些;
所以我們一般開發(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自動為我們創(chuàng)建了Library.h/.m文件以及相對應(yīng)的目錄結(jié)構(gòu),如圖2所示:
(3)接下來我們在工程的.h和.m里面編寫功能實(shí)現(xiàn)的代碼(重在靜態(tài)庫的創(chuà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)目生成對應(yīng)的靜態(tài)庫.a文件(在這里注意一下細(xì)節(jié)):
①在工程編譯(Command+B)之前"標(biāo)號為②的框框中l(wèi)ibLibrary.a"為紅色(編譯之后為黑色, 紅色表示一個虛擬的文件工程中找不到它),如圖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)錯誤),打開終端查看靜態(tài)庫的架構(gòu)如圖8所示:
我們找到原因如圖9所示,下面Debug:Yes表示只編譯選中模擬器對應(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ī)和模擬器上,但要滿足這要求的話,要對編譯好的兩個靜態(tài)庫進(jìn)行合并在使用;
②合并靜態(tài)庫的利弊?
1)利:開發(fā)過程中既可以在真機(jī)上調(diào)試,也可以在模擬器上調(diào)試;
2)弊:如果靜態(tài)庫太大,合并打包后,會非常大,因此很多第三方的靜態(tài)庫的.a是區(qū)分版本的;
③打開終端合并靜態(tài)庫(終于快成功了😄😄...)如圖10所示:
其中完整的命令是:
(8)靜態(tài)庫的使用:
將合并好的靜態(tài)庫文件(.a)和頭文件(.h)添加到工程里面,調(diào)用靜態(tài)庫,結(jié)果如下(代碼粗略請大家無視...):
"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)容;
以上就是我對iOS靜態(tài)庫的理解與解釋,希望大家相互補(bǔ)充相互學(xué)習(xí)。
相關(guān)文章
iOS列表上拉(平滑加載數(shù)據(jù))自動加載數(shù)據(jù)的問題解決
這篇文章主要給大家介紹了關(guān)于iOS列表上拉(平滑加載數(shù)據(jù))自動加載數(shù)據(jù)問題的相關(guān)資料,本文實(shí)現(xiàn)的效果很多app都用的這種效果,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07iOS NSURLSessionDownloadTask實(shí)現(xiàn)文件斷點(diǎn)下載的方法
本篇文章主要介紹了iOS NSURLSessionDownloadTask實(shí)現(xiàn)文件斷點(diǎn)下載的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01iOS 將系統(tǒng)自帶的button改裝成上圖片下文字的樣子
這篇文章主要介紹了 iOS 將系統(tǒng)自帶的button改裝成上圖片下文字的樣子,代碼是通過繼承UIButton,然后再重寫layoutSubviews方法,對自帶的圖片和titleLabel進(jìn)行重新的layout。下面通過本文給大家分享下實(shí)現(xiàn)代碼2016-12-12基于UIControl控件實(shí)現(xiàn)ios點(diǎn)贊功能
在開發(fā)當(dāng)中,可能很多時(shí)候都需要做個點(diǎn)贊的需求,如果用按鈕實(shí)現(xiàn),按鈕作為一個系統(tǒng)復(fù)合控件,外部是一個 View--》UIControl的容器,本文給大家分享一個基于UIControl控件實(shí)現(xiàn)ios點(diǎn)贊功能,需要的朋友可以參考下2015-09-09iOS10 App適配權(quán)限 Push Notifications 字體Frame 遇到的問題
這篇文章主要介紹了iOS10 App適配權(quán)限 Push Notifications 字體Frame 遇到的問題,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09