隨著業(yè)務(wù)的發(fā)展或者項目的增長斧拍,為了更好的維護代碼,在項目的開發(fā)后期都會對項目的一些公有組件和基礎(chǔ)業(yè)務(wù)進行封裝记焊。最近由于一個人需要負責(zé)多個SDK的開發(fā)芳杏,后續(xù)公司可能還會繼續(xù)開發(fā)新的SDK,對于每一個新的SDK的開發(fā)抡柿,如果我都從底層的基礎(chǔ)庫(網(wǎng)絡(luò)舔琅,解析,工具類等)再到業(yè)務(wù)邏輯層都重新開發(fā)的話洲劣,會需要很多的時間备蚓,并且在開發(fā)過程中會發(fā)現(xiàn)不同的SDK除了具體的業(yè)務(wù)邏輯不一樣的話,其他基本一致囱稽。所以對于需要快速的去試錯開發(fā)一個SDK的話郊尝,抽離封裝基組件庫和公共業(yè)務(wù)勢在必行,不然代碼拷來拷去很容易出錯战惊,吃力不討好流昏。
整體的架構(gòu)思想就是,抽離公共組件庫和公共業(yè)務(wù)代碼庫吞获,做成一個通用的libCommon.a供其他SDK使用况凉,這樣做的好處很多:
- 通用庫一次開發(fā),享用一生各拷;
- 新的SDK開發(fā)刁绒,只需要專注具體SDK業(yè)務(wù)邏輯的開發(fā);節(jié)約開發(fā)時間烤黍;
libCommon.a分解
在通用基礎(chǔ)庫中主要包括兩部分知市,一部分是公共組件庫,一部分是公共業(yè)務(wù)模塊蚊荣。
- 公共業(yè)務(wù)模塊:我們一般只需要SDK部分幫我們啟動業(yè)務(wù)就好初狰,或者再增加一些回調(diào)處理。他的頭文件一般也只會有一個互例。
- 公共組件模塊:有很多子模塊奢入,例如數(shù)據(jù)解析,字符串處理,存儲腥光、網(wǎng)絡(luò)基礎(chǔ)庫等等关顷,這樣的話我們就需要公開很多的頭文件,因此我想到了先使用Framework來封裝公共組件武福,然后再讓libCommon.a來引用Framework议双,最后我在SDK中通過libCommon.a使用這個Framework。整體架構(gòu)就會變成下面這樣:
錯誤的原因
首先說下為什么我要把多個公共組件制作成一個Framework捉片,因為這樣的話SDK在調(diào)用的時候不需要添加很多的.h頭文件平痰。想法是很完美,但是現(xiàn)實卻很殘酷伍纫,我在實現(xiàn)的過程中l(wèi)ibCommon.a引用了Framework宗雇,但是我繼續(xù)在我的libSDK1.a里面繼續(xù)用的時候,發(fā)現(xiàn)會報錯(Undefined symbols for architecture x86_64)莹规,在Framework里面定義的方法都找不到了赔蒲,出現(xiàn)這個的原因就是沒有在運行的時候沒有找到實現(xiàn)文件,所以動態(tài)去鏈接找方法的時候出了問題良漱。這里我們需要明白Static Library和Framework的編譯原理舞虱。
- Static Library編譯的時候會把所有的代碼編譯進去;
- Framework編譯的時候只是進行鏈接母市,函數(shù)在調(diào)用的時候才會去尋找實現(xiàn)矾兜,所以在編譯過程Framework里面的組件代碼沒有被編譯到libCommon.a里面,所以我們在上層調(diào)用的時候還是需要引用Framework的窒篱,所以這里就不適合我的開發(fā)場景了焕刮,因為我封裝的Framework是不想對外公開的,只能我內(nèi)部知道和使用墙杯。
最后我還是回到原點配并,將公共組件編譯成靜態(tài)庫然后公開多個頭文件來處理。