iOS-SDK開(kāi)發(fā)之制作自己的靜態(tài)庫(kù) .framework和.a文件

先來(lái)看幾個(gè)概念定義:

  • 什么是庫(kù)?
    庫(kù)是共享程序代碼的方式,一般分為靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)规哪。
  • 靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的區(qū)別蛤袒?
    靜態(tài)庫(kù):鏈接時(shí)完整地拷貝至可執(zhí)行文件中熄云,唄多次使用就有多分冗余拷貝
    動(dòng)態(tài)庫(kù):鏈接時(shí)不復(fù)制,程序運(yùn)行時(shí)由系統(tǒng)動(dòng)態(tài)加載到內(nèi)存妙真,供程序調(diào)用缴允,系統(tǒng)只加載一次,多個(gè)程序共用珍德,節(jié)省內(nèi)存
  • iOS里靜態(tài)庫(kù)的形式练般?
    .a 和 .framework
  • iOS動(dòng)態(tài)庫(kù)的形式?
    .dylib 和 .framework
  • framework為什么既是靜態(tài)庫(kù)有事動(dòng)態(tài)庫(kù)锈候?
    系統(tǒng)的.framework是動(dòng)態(tài)庫(kù)踢俄,我們自己建立的.framework是靜態(tài)庫(kù)
  • .a 和 .framework有什么區(qū)別?
    .a 是一個(gè)純二進(jìn)制文件,.framework中除了有二進(jìn)制文件之外還有資源文件
    .a 文件不能直接使用晴及,至少要有.h文件配合都办,.framework文件可以直接使用
    .a + .h +sourceFile = .framework
  • 為什么使用靜態(tài)庫(kù)?
    方便共享代碼虑稼,便于合理使用琳钉。(懶逼格高)
    實(shí)現(xiàn)iOS程序的模塊化≈刖耄可以把固定的業(yè)務(wù)模塊化成靜態(tài)庫(kù)歌懒。(懶高大上)
    和別人分享你的代碼庫(kù),但不想讓別人看到你代碼的實(shí)現(xiàn)溯壶。(怕被噴)
    開(kāi)發(fā)第三方SDK的需要及皂。

我們可以看出.a的封裝和.framework的封裝差不多,也有模擬器和真機(jī)合并的過(guò)程且改,通過(guò)上邊的圖片我們可以看出.a 和.framework的區(qū)別验烧,就是.a+.h+soureFile=.framework∮瞩耍可以看出我們直接封裝.framework其實(shí)是最好的碍拆。不啰嗦了,先來(lái)看看.a文件是怎么封裝的

一 .a文件的封裝

(一)創(chuàng)建一新工程TestSDK,選擇Framework & Library中的 Cocoa Touch Static Library感混,如圖1

圖1.jpg
工程中會(huì)看到TestSDK.h和TestSDK.m文件端幼,干掉TestSDK.m文件到垃圾桶
只留下.h文件就可以。
(二)創(chuàng)建你要封裝的模塊弧满,由于本文主要是講述制作流程這里我直接拖入一個(gè)模塊如圖2:
圖2.jpg
Add to targets 一定要勾選婆跑!一定要勾選!一定要勾選庭呜!
在TestSDK.h中引入你的控件的頭文件ChannelAlert.h即可洽蛀。
(三)分別選擇模擬器和真機(jī)編譯工程,在Products下會(huì)生成.a文件疟赊,show in finder會(huì)發(fā)現(xiàn)如圖3兩個(gè).a文件
圖3.jpg

iphoneos 適用于真機(jī),iphonesimulator適用于模擬器峡碉。打開(kāi)終端合并兩個(gè)文件成為通用版本近哟,命令

lipo -create
模擬器.a文件目錄  
真機(jī).a文件目錄
-output  輸出目錄/文件

如圖4:
圖4.jpg

(嘿嘿是不是很紅)
看到libTestSDK.a了吧,這就是通用版本的.a文件
(四)使用方法:

將libTestSDK.a鲫寄,ChannelAlert.h吉执,TestSDK.h放到一個(gè)文件夾下,取個(gè)名字如圖5:
圖5.jpg

將此文件夾拖入到你需要使用的工程中地来,在需要的地方導(dǎo)入頭文件TestSDK.h如圖6:
圖6.jpg

功能按照你正常的使用方式就可以了戳玫。看看我的效果
圖7.jpg

到此簡(jiǎn)單的.a文件制作完成了未斑,下面我們來(lái)看看更好的framework是如何制作的

二 .framework文件的封裝

(一)創(chuàng)建工程TestFramework,如圖F1:


F1.jpg

(二)創(chuàng)建自己的類(lèi)咕宿,Tool.h,Tool.m,如圖F2:
F2.jpg

如果有依賴庫(kù)就要添加依賴庫(kù)(本文重點(diǎn)是流程,這里就不多加贅述)蜡秽。在TestFramework.h中#import "Tool.h"府阀。
(三)在Build Phases->Headers中設(shè)置你要暴露的接口,主要設(shè)置Public和Private芽突,這里我把Tool.h移動(dòng)到了Public中如圖:
F3.png

選擇模擬器和真機(jī)试浙,分別編Command+B一次,

在工程目錄Products show in Finder可以看到兩個(gè)framework分別對(duì)應(yīng)模擬器和真機(jī)如圖:
F4.jpg

iphoneos 對(duì)應(yīng)的是真機(jī)寞蚌,iphonesimulator對(duì)應(yīng)的模擬器

下面我們將兩個(gè)framework合并田巴,要用到腳本語(yǔ)言

if [ "${ACTION}" = "build" ]
then
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}.framework
DEVICE_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
SIMULATOR_DIR=${BUILD_ROOT}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
mkdir -p "${INSTALL_DIR}"
cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/"
#ditto "${DEVICE_DIR}/Headers" "${INSTALL_DIR}/Headers"
lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"
#open "${DEVICE_DIR}"
open "${SRCROOT}/Products"
fi

如圖:
F5.png

在4位置添加上面的腳本,然后Run(xcode左上角的黑三角)之后會(huì)彈框在Products里面就可以看到TestFramework.framework了挟秤。
(四)使用方法

將改TestFramework.framework拖入到你需要的工程中(如過(guò)有依賴庫(kù)壹哺,記得添加依賴庫(kù)),因?yàn)樾枰尵幾g器提前編譯這個(gè)二進(jìn)制文件艘刚。進(jìn)入General->Embedded Binaries,將加入的framework添加上去斗躏。如圖:
F6.jpg

在你需要的地方導(dǎo)入頭文件:如圖
屏幕快照 2018-04-26 17.18.02.png

至此,簡(jiǎn)單的.framework就算是制作完成了。這也僅是一個(gè)流程啄糙,畢竟framework博大精深笛臣。寫(xiě)一點(diǎn)注意事項(xiàng)吧
1、.h文件的外漏一定要保證是自己的想要外漏的隧饼。不想外漏的就別外漏了沈堡。
2、開(kāi)始打包的時(shí)候燕雁,一定要在選中模擬器和選中真機(jī)上邊分別編譯一次诞丽, 我覺(jué)得之前在家里沒(méi)有真機(jī)的時(shí)候編譯的好像不對(duì)。
3拐格、終端也可以合并(這里就不寫(xiě)了僧免,有興趣的可以自己搜一搜),在終端上邊合并的時(shí)候可能是error并生成一個(gè).lipo文件捏浊,不要怕懂衩,大膽修改成同名的不掛后綴的同名文件。
4金踪、調(diào)用的時(shí)候分清楚是類(lèi)方法還是實(shí)例方法浊洞,方便調(diào)用。
5胡岔、在制作framework或者lib的時(shí)候法希,如果使用了category,則使用改FMWK的程序運(yùn)行時(shí)會(huì)crash靶瘸,此時(shí)需要在該工程中 other linker flags添加兩個(gè)參數(shù) -ObjC -all_load苫亦。(這點(diǎn)沒(méi)有親測(cè))
6、帶有圖片資源的需要把圖片打包成Bundle文件怨咪,和framework一起拷貝到相應(yīng)的項(xiàng)目中著觉。
7、公開(kāi)的類(lèi)中如果引用的private的類(lèi)惊暴,打包以后對(duì)外會(huì)報(bào)錯(cuò)饼丘,找不到那個(gè)private的類(lèi),可以把那個(gè)private的.h放到(也沒(méi)親測(cè))
8辽话、**namespace 沖突肄鸽。**靜態(tài)庫(kù)用了某第三方庫(kù),項(xiàng)目也用了同樣的第三方庫(kù)油啤,在編譯的時(shí)候就會(huì)有 duplicate symbol 錯(cuò)誤典徘,因?yàn)橛袃煞萃瑯拥牡谌綆?kù)。解決辦法就是把用到的第三方庫(kù)加上自定義前綴益咬,包括類(lèi)名逮诲、delegate 協(xié)議、常量名,尤其需要注意 Category 的方法名要修改梅鹦。
9裆甩、封裝靜態(tài)庫(kù)的時(shí)候應(yīng)盡量避免引入重量級(jí)第三方庫(kù),**多自己進(jìn)行封裝**齐唆。
10嗤栓、一個(gè)靜態(tài)庫(kù)要**有自己獨(dú)有的前綴**,所有類(lèi)名箍邮、常量等都要加同樣的前綴茉帅。
11、**真機(jī)+模擬器支持**锭弊。(和第2條意思一樣)Xcode 默認(rèn)只會(huì)用當(dāng)前環(huán)境(真機(jī)或模擬器)生成靜態(tài)庫(kù)堪澎,這樣的 SDK 不方便其他項(xiàng)目開(kāi)發(fā)時(shí)調(diào)試。解決辦法就是通過(guò)腳本生成一份通用庫(kù)味滞,build_universal_library.sh樱蛤,via SO.
12、**文檔**桃犬。靜態(tài)庫(kù)的方便是使用者直接拿你提供的方法來(lái)用,無(wú)需關(guān)注具體實(shí)現(xiàn)行楞;不方便在于看不到實(shí)現(xiàn)攒暇,出現(xiàn)問(wèn)題無(wú)法排查,因此需要把 SDK 的版本子房、更新歷史形用、使用、FAQ 等寫(xiě)成文檔证杭,方便使用田度,也顯得 SDK 比較正式規(guī)范。
13解愤、圖片等資源文件用 **bundle** 方式打包镇饺。一個(gè)簡(jiǎn)單制作 bundle 的方法:新建文件夾,重命名為 YourSDK.bundle送讲,然后 Show Package Contents 打開(kāi)奸笤,加入圖片。使用圖片的時(shí)候需要指明 bundle: [UIImage imageNamed:@"YourSDK.bundle/img.png"]哼鬓。也可以用 Target 方式制作 bundle监右。
14、如果 SDK 有用到 **Category**异希,注意項(xiàng)目設(shè)置 Other Linker Flags 添加 -ObjC健盒。

編譯過(guò)程:
從C代碼到可執(zhí)行文件經(jīng)歷的步驟是:源代碼 > 預(yù)處理器 > 編譯器 > 匯編器 > 機(jī)器碼 > 鏈接器 > 可執(zhí)行文件

在最后一步需要把.o文件和C語(yǔ)言運(yùn)行庫(kù)鏈接起來(lái),這時(shí)候需要用到ld命令。源文件經(jīng)過(guò)一系列處理以后扣癣,會(huì)生成對(duì)應(yīng)的.obj文件惰帽,然后一個(gè)項(xiàng)目必然會(huì)有許多.obj文件,并且這些文件之間會(huì)有各種各樣的聯(lián)系搏色,例如函數(shù)調(diào)用善茎。鏈接器做的事就是把這些目標(biāo)文件和所用的一些庫(kù)鏈接在一起形成一個(gè)完整的可執(zhí)行文件。Other linker flags設(shè)置的值實(shí)際上就是ld命令執(zhí)行時(shí)后面所加的參數(shù)

下面逐個(gè)介紹3個(gè)常用參數(shù):
-ObjC:加了這個(gè)參數(shù)后频轿,鏈接器就會(huì)把靜態(tài)庫(kù)中所有的Objective-C類(lèi)和分類(lèi)都加載到最后的可執(zhí)行文件中

-all_load:會(huì)讓鏈接器把所有找到的目標(biāo)文件都加載到可執(zhí)行文件中垂涯,但是千萬(wàn)不要隨便使用這個(gè)參數(shù)!假如你使用了不止一個(gè)靜態(tài)庫(kù)文件航邢,然后又使用了這個(gè)參數(shù)耕赘,那么你很有可能會(huì)遇到ld: duplicate symbol錯(cuò)誤,因?yàn)椴煌膸?kù)文件里面可能會(huì)有相同的目標(biāo)文件膳殷,所以建議在遇到-ObjC失效的情況下使用-force_load參數(shù)操骡。

-force_load:所做的事情跟-all_load其實(shí)是一樣的,但是-force_load需要指定要進(jìn)行全部加載的庫(kù)文件的路徑赚窃,這樣的話册招,你就只是完全加載了一個(gè)庫(kù)文件,不影響其余庫(kù)文件的按需加載

研究不深勒极,歡迎各位來(lái)指點(diǎn)是掰。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辱匿,隨后出現(xiàn)的幾起案子键痛,更是在濱河造成了極大的恐慌,老刑警劉巖匾七,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件絮短,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡昨忆,警方通過(guò)查閱死者的電腦和手機(jī)丁频,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)邑贴,“玉大人限府,你說(shuō)我怎么就攤上這事×《校” “怎么了胁勺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)独旷。 經(jīng)常有香客問(wèn)我署穗,道長(zhǎng)寥裂,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任案疲,我火速辦了婚禮封恰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘褐啡。我一直安慰自己诺舔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布备畦。 她就那樣靜靜地躺著低飒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪懂盐。 梳的紋絲不亂的頭發(fā)上褥赊,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音莉恼,去河邊找鬼拌喉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛俐银,可吹牛的內(nèi)容都是我干的尿背。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼捶惜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼田藐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起售躁,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坞淮,失蹤者是張志新(化名)和其女友劉穎茴晋,沒(méi)想到半個(gè)月后陪捷,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诺擅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年市袖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烁涌。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡苍碟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出撮执,到底是詐尸還是另有隱情微峰,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布抒钱,位于F島的核電站蜓肆,受9級(jí)特大地震影響颜凯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仗扬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一症概、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧早芭,春花似錦彼城、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至帜乞,卻和暖如春司抱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背黎烈。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工习柠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人照棋。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓资溃,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親烈炭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子溶锭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容