2018 iOS 組件化

image

一. 組件化的需求

在 iOS Native app 前期開(kāi)發(fā)的時(shí)候,如果參與的開(kāi)發(fā)人員也不多,那么代碼大多數(shù)都是寫(xiě)在一個(gè)工程里面的蚀苛,這個(gè)時(shí)候業(yè)務(wù)發(fā)展也不是太快在验,所以很多時(shí)候也能保證開(kāi)發(fā)效率。

但是一旦項(xiàng)目工程龐大以后枉阵,開(kāi)發(fā)人員也會(huì)逐漸多起來(lái)译红,業(yè)務(wù)發(fā)展突飛猛進(jìn),這個(gè)時(shí)候單一的工程開(kāi)發(fā)模式就會(huì)暴露出弊端了兴溜。

  • 項(xiàng)目?jī)?nèi)代碼文件耦合比較嚴(yán)重
  • 容易出現(xiàn)沖突侦厚,大公司同時(shí)開(kāi)發(fā)一個(gè)項(xiàng)目的人多,每次 pull 一下最新代碼就會(huì)有很多沖突拙徽,有時(shí)候合并代碼需要半個(gè)小時(shí)左右刨沦,這會(huì)耽誤開(kāi)發(fā)效率。
  • 業(yè)務(wù)方的開(kāi)發(fā)效率不夠高膘怕,開(kāi)發(fā)人員一多想诅,每個(gè)人都只想關(guān)心自己的組件,但是卻要編譯整個(gè)項(xiàng)目岛心,與其他不相干的代碼糅合在一起来破。調(diào)試起來(lái)也不方便,即使開(kāi)發(fā)一個(gè)很小的功能忘古,都要去把整個(gè)項(xiàng)目都編譯一遍徘禁,調(diào)試效率低。

為了解決這些問(wèn)題髓堪,iOS 項(xiàng)目就出現(xiàn)了組件化的概念送朱。所以 iOS 的組件化是為了解決上述這些問(wèn)題的,這里與前端組件化解決的痛點(diǎn)不同干旁。

iOS 組件化以后能帶來(lái)如下的好處:

  • 加快編譯速度(不用編譯主客那一大坨代碼了驶沼,各個(gè)組件都是靜態(tài)庫(kù))
  • 自由選擇開(kāi)發(fā)姿勢(shì)(MVC / MVVM / FRP)
  • 方便 QA 有針對(duì)性地測(cè)試
  • 提高業(yè)務(wù)開(kāi)發(fā)效率

iOS 組件化的封裝性只是其中的一小部分,更加關(guān)心的是如何拆分組件争群,如何解除耦合回怜。前端的組件化可能會(huì)更加注重組件的封裝性,高可復(fù)用性换薄。

二. 如何封裝組件

iOS 的組件化手段非常單一玉雾,就是利用 Cocoapods 封裝成 pod 庫(kù),主工程分別引用這些 pod 即可专控。越來(lái)越多的第三方庫(kù)也都在 Cocoapods 上發(fā)布自己的最新版本抹凳,大公司也在公司內(nèi)部維護(hù)了公司私有的 Cocoapods 倉(cāng)庫(kù)遏餐。一個(gè)封裝完美的 Pod 組件伦腐,主工程使用起來(lái)非常方便。

具體如果用 Cocoapods 打包一個(gè)靜態(tài)庫(kù) .a 或者 framework 失都,網(wǎng)上教程很多柏蘑,這里給一個(gè)鏈接幸冻,詳細(xì)的操作方法就不再贅述了。

image

最終想要達(dá)到的理想目標(biāo)就是主工程就是一個(gè)殼工程咳焚,其他所有代碼都在組件 Pods 里面洽损,主工程的工作就是初始化,加載這些組件的革半,沒(méi)有其他任何代碼了碑定。

三. 如何劃分組件

iOS 劃分組件雖然沒(méi)有一個(gè)很明確的標(biāo)準(zhǔn),因?yàn)槊總€(gè)項(xiàng)目都不同又官,劃分組件的粗粒度也不同延刘,但是依舊有一個(gè)劃分的原則。

App之間可以重用的 Util六敬、Category碘赖、網(wǎng)絡(luò)層和本地存儲(chǔ) storage 等等這些東西抽成了 Pod 庫(kù)。還有些一些和業(yè)務(wù)相關(guān)的外构,也是在各個(gè)App之間重用的普泡。

原則就是:要在App之間共享的代碼就應(yīng)該抽成 Pod 庫(kù),把它們作為一個(gè)個(gè)組件审编。不在 App 間共享的業(yè)務(wù)線撼班,也應(yīng)該抽成 Pod,解除它與工程其他的文件耦合性割笙。

常見(jiàn)的劃分方法都是從底層開(kāi)始動(dòng)手权烧,網(wǎng)絡(luò)庫(kù),路由伤溉,MVVM框架般码,數(shù)據(jù)庫(kù)存儲(chǔ),加密解密乱顾,工具類板祝,地圖,基礎(chǔ)SDK走净,APM券时,風(fēng)控,埋點(diǎn)……從下往上伏伯,到了上層就是各個(gè)業(yè)務(wù)方的組件了橘洞,最常見(jiàn)的就類似于購(gòu)物車,我的錢(qián)包说搅,登錄炸枣,注冊(cè)等。

四. 組件化原理

iOS 的組件化原理是基于 Cocoapods 的。關(guān)于 Cocoapods 的具體工作原理适肠,可以看這篇文章《CocoaPods 都做了什么霍衫?》

這里簡(jiǎn)單的分析一下 pod進(jìn)來(lái)的庫(kù)是什么加載到主工程的侯养。

pod 會(huì)依據(jù) Podfile 文件里面的依賴庫(kù)敦跌,把這些庫(kù)的源代碼下載下來(lái),并創(chuàng)建好 Pods workspace逛揩。當(dāng)程序編譯的時(shí)候柠傍,會(huì)預(yù)先執(zhí)行2個(gè) pod設(shè)置進(jìn)來(lái)的腳本。

image

在上面這個(gè)腳本中辩稽,會(huì)把 Pods 里面的打包好的靜態(tài)庫(kù)合并到 libPods-XXX.a 這個(gè)靜態(tài)庫(kù)里面携兵,這個(gè)庫(kù)是主工程依賴的庫(kù)。

<figure>
image

上圖就是給主項(xiàng)目加載 Pods 庫(kù)的腳本搂誉。

Pods 另外一個(gè)腳本是加載資源的徐紧。見(jiàn)下圖。

image

這里加載的資源是 Pods 庫(kù)里面的一些圖片資源炭懊,或者是 Boudle 里面的 xib 并级,storyboard,音樂(lè)資源等等侮腹。這些資源也會(huì)一起打到 libPods-XXX.a 這個(gè)靜態(tài)庫(kù)里面嘲碧。

image

上圖就是加載資源的腳本。

五. 組件分類

iOS 的組件主要分為2種形式:

  1. 靜態(tài)庫(kù)
  2. 動(dòng)態(tài)庫(kù)

靜態(tài)庫(kù)一般是以 .a 和 .framework 結(jié)尾的文件父阻,動(dòng)態(tài)庫(kù)一般是以 .dylib 和 .framework 結(jié)尾的文件愈涩。

這里可以看到,一個(gè) .framework 結(jié)尾的文件僅僅通過(guò)文件類型是無(wú)法判斷出它是一個(gè)靜態(tài)庫(kù)還是一個(gè)動(dòng)態(tài)庫(kù)加矛。

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

  1. .a文件肯定是靜態(tài)庫(kù)履婉,.dylib肯定是動(dòng)態(tài)庫(kù),.framework可能是靜態(tài)庫(kù)也可能是動(dòng)態(tài)庫(kù)斟览;

  2. 靜態(tài)庫(kù)在鏈接其他庫(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)定義的;靜態(tài)庫(kù)的好處很明顯躁绸,編譯完成之后裕循,庫(kù)文件實(shí)際上就沒(méi)有作用了丙猬。目標(biāo)程序沒(méi)有外部依賴,直接就可以運(yùn)行费韭。當(dāng)然其缺點(diǎn)也很明顯,就是會(huì)使用目標(biāo)程序的體積增大庭瑰。

  3. 動(dòng)態(tài)庫(kù)不會(huì)被復(fù)制星持,只有一份,程序運(yùn)行時(shí)動(dòng)態(tài)加載到內(nèi)存中弹灭,系統(tǒng)只會(huì)加載一次督暂,多個(gè)程序共用一份,節(jié)約了內(nèi)存穷吮。而且使用動(dòng)態(tài)庫(kù)逻翁,可以不重新編譯連接可執(zhí)行程序的前提下,更新動(dòng)態(tài)庫(kù)文件達(dá)到更新應(yīng)用程序的目的捡鱼。

六. 組件間的消息傳遞和狀態(tài)管理

之前我們討論過(guò)了八回,iOS 組件化十分關(guān)注解耦性,這算是組件化的一個(gè)重要目的驾诈。iOS 各個(gè)組件之間消息傳遞是用路由來(lái)實(shí)現(xiàn)的缠诅。關(guān)于路由,筆者曾經(jīng)寫(xiě)過(guò)一篇比較詳細(xì)的文章乍迄,感興趣的可以來(lái)看這篇文章《iOS 組件化 —— 路由設(shè)計(jì)思路分析》管引。

七. 組件注冊(cè)方式

iOS 組件注冊(cè)的方式主要有3種:

  1. load方法注冊(cè)
  2. 讀取 plist 文件注冊(cè)
  3. Annotation注解方式注冊(cè)

前兩種方式都比較簡(jiǎn)單,容易理解闯两。

第一種方式在 load 方法里面利用 Runtime 把組件名和組件實(shí)例的映射關(guān)系保存到一個(gè)全局的字典里褥伴,方便程序啟動(dòng)以后可以隨時(shí)調(diào)用。

第二種方式是把組件名和組件實(shí)例的映射關(guān)系預(yù)先寫(xiě)在 plist 文件中漾狼。程序需要的時(shí)候直接去讀取這個(gè) plist 文件重慢。plist 文件可以從服務(wù)器讀取過(guò)來(lái),這樣 App 還能有一定的動(dòng)態(tài)性逊躁。

第三種方式比較黑科技伤锚。利用的是 Mach-o 的數(shù)據(jù)結(jié)構(gòu),在程序編程鏈接成可執(zhí)行文件的時(shí)候志衣,就把相關(guān)注冊(cè)信息直接寫(xiě)入到最終的可執(zhí)行文件的 Data 數(shù)據(jù)段內(nèi)屯援。程序執(zhí)行以后,直接去那個(gè)段內(nèi)去讀取想要的數(shù)據(jù)即可念脯。

關(guān)于這三種做法的詳細(xì)實(shí)現(xiàn)狞洋,可以看筆者之前的一篇文章《BeeHive —— 一個(gè)優(yōu)雅但還在完善中的解耦框架》,在這篇文章里面詳細(xì)的分析了上述3種注冊(cè)過(guò)程的具體實(shí)現(xiàn)绿店。


文中鏈接都已失效,想看的話留言發(fā)給你新的地址

作者:一縷殤流化隱半邊冰霜

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吉懊,一起剝皮案震驚了整個(gè)濱河市庐橙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌借嗽,老刑警劉巖态鳖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異恶导,居然都是意外死亡浆竭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)惨寿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)邦泄,“玉大人,你說(shuō)我怎么就攤上這事裂垦∷衬遥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵蕉拢,是天一觀的道長(zhǎng)特碳。 經(jīng)常有香客問(wèn)我,道長(zhǎng)晕换,這世上最難降的妖魔是什么测萎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮届巩,結(jié)果婚禮上硅瞧,老公的妹妹穿的比我還像新娘。我一直安慰自己恕汇,他們只是感情好腕唧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著瘾英,像睡著了一般枣接。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缺谴,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天但惶,我揣著相機(jī)與錄音,去河邊找鬼湿蛔。 笑死膀曾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的阳啥。 我是一名探鬼主播添谊,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼察迟!你這毒婦竟也來(lái)了斩狱?” 一聲冷哼從身側(cè)響起耳高,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎所踊,沒(méi)想到半個(gè)月后泌枪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秕岛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年碌燕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓣蛀。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖雷厂,靈堂內(nèi)的尸體忽然破棺而出惋增,到底是詐尸還是另有隱情,我是刑警寧澤改鲫,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布诈皿,位于F島的核電站,受9級(jí)特大地震影響像棘,放射性物質(zhì)發(fā)生泄漏稽亏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一缕题、第九天 我趴在偏房一處隱蔽的房頂上張望截歉。 院中可真熱鬧,春花似錦烟零、人聲如沸瘪松。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宵睦。三九已至,卻和暖如春墅诡,著一層夾襖步出監(jiān)牢的瞬間壳嚎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工末早, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烟馅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓然磷,卻偏偏與公主長(zhǎng)得像焙糟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子样屠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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