一.概述
objc公用庫的使用場景還是比較常見的,iOS SDK本身就是公用庫的集合;一些開放平台為了方便開發者開發第三方的app,提供相應平台的sdk;還有一個場景就是比較大的公司一般會有多個甚至幾十個app,各個app之間勢必會有重復的邏輯,為了 “提升效率”“安全性” 或者業務指標,會推一些公用的庫供內部各個app使用。
公用庫本質上就是一些可重用邏輯的集合,是“分而治之”的一種途徑,其出現的形式可以是源碼亦或是二進制。
公用庫也需要理清自己的依賴關系,比如依賴系統SDK的哪些庫的哪些接口(決定了公用庫適用的系統版本),依賴哪些第三方的庫。不過你想把一個東西拿出去給別人用,那你就得想方設法去減少不必要的依賴。
作為一個公用庫的開發者,提供公用庫給別人使用時,需要站在使用者的角度去思考問題,公用庫的接口以及接入使用的繁簡體現了公用庫作者的職業道德和素養。
二.設計與實現
第一步當然是明確公用庫的目標,要做什麼,不做什麼,一二三四列出來,並在後繼的實現中最大可能地堅持目標原則。
項目的構建也有幾種選擇:
另外你可以在上面的基礎上,通過cocoapods來管理你自己的公用庫的依賴。
在實現的時候,公用庫自身的源碼全都放到某個目錄中或者其子目錄中(是指那些可以直接拷貝出去使用的源碼,不包括自身編譯所依賴的文件,比如prefix.pch)。
頭文件只暴漏那些必須的,在實現庫的時候能夠在實現文件中進行引入的的則在實現文件中進行引入,如果在需要暴漏的頭文件中引入另一個頭文件,那麼這另一個頭文件也必須要暴漏出來。
另一個常見的問題便是接口的方法聲明不遵循objc的語言規范,給人以山寨的感覺。還是建議公用庫的實現最好有一個當前語言的老手帶著做,熟悉當前語言的規范和常用的范式,比如何時使用delegate,何時使用block。
還有就是在實現的時候盡可能少地引入第三方的依賴,如果確實需要引入,那麼編譯的時候千萬別把公用庫自身依賴的第三方的內容當成自己的一部分,如果你很變態,硬要把第三方的內容搞成自己的一部分,那麼你至少得修改這些依賴的相關類的類名,靜態變量名,如果是category,還得修改其方法名。
最後就是你得堅持良好的注釋和文檔 ,某個方法 如有特殊的需要注意的點,則需要注釋說明,你還得提供一個README文件,用於描述當前庫的目的,以及各個接口的使用范例。
三.分發與集成
其實在公用庫構建的初期,你就得想好分發的方式。一種好的分發方式可以大大降低公用庫集成使用的成本。
一個公用庫要給別人用,無非就兩種形式:源碼或者二進制格式(額外提供頭文件,資源文件),源碼的形式,方便使用者進行調試,二進制格式則適用於那些不方便公開源碼的公用庫。
當然不管你以何種方式分發你的公用庫,你都得明確聲明此公用庫適用的系統版本,依賴哪些系統SDK的框架或者靜態庫,依賴哪些第三方的庫以及對應的版本,這是對自己負責也是對別人負責。
在使用公用庫的時候,XCode都是通過header search path來尋找靜態庫的頭文件的,通過framework search path來尋找framework的,當使用cocoapods來管理的時候,這些環境變量的設置都是自動幫你完成的,在其生成的xcconfig文件中。
四.和庫相關的幾個命令
下面幾個命令都是和二進制庫相關的,這些二進制文件可以叫做對象文件,在Mac或者iOS平台中用的都是Mach-O(Mach Object),所以這些命令其實都是讀取或者操作Mach Object的,你可以通過man來查看相應的詳情用戶手冊。
display name list (symbol table),其實就是把對象文件中的相關符號標識都列出來
otool,顧名思義就是object tool,比其nm來說,其功能更強大,可以查看對象文件的方方面面,比如展示對象文件的Mach Header,用到了哪些共享庫(shared libraries),或者數據段內容等。
create or operate on universal files,此命令主要是幫你查看或者創建支付多平台的靜態庫的。比如將兩台不同平台的靜態進行合並。