第15條:用前綴避免命名空間沖突
我們在構建應用程序時,可能想將其中部分代碼用於後續項目,也可能想把某些代碼發布出來,供他人使用。即便現在還不想這麽做,將來也總會有用到的時候。如果決定重用代碼,那麽我們在編寫接口時就會將其設計成易於復用的形式。這需要用到 Objective-C 語言中常見的編程範式(paradigm),同時還需了解各種可能碰到的陷阱。
近年來,開源社區與開源組件隨著iOS 開發而流行起來,所以我們經常會在開發自己的應用程序時使用他人所寫的代碼。與此同時,別人也會用到你的代碼,所以,要把代碼寫得清晰一些,以便其他開發者能夠迅速而方便地將其集成到他們的項目裏。
本條要點:(作者總結)
Objective-C 沒有其他語言那種內置的命名空間(namespace)機制。鑒於此,我們在起名時要設法避免潛在的命名沖突,否則很容易就重名了。如果發生命名沖突(naming clash),那麽應用程序的鏈接過程就會出錯,因為其中出現了重復符號:
1 duplicate symbol _OBJC_METACLASS_$_EOCTheClass in: 2 build/something.o 3 build/something_else.o 4 duplicate symbol _OBJC_CLASS_$_EOCTheClass in: 5 build/something.o 6 build/something_else.o
錯誤原因在於,應用程序中的兩份代碼都各自實現了名為 EOCTheClass 的類,這導致 EOCTheClass 所對應的類符號和 “元類”符號各定義了兩次。你也許是把兩個相互獨立的程序庫都引入到當前項目中,而它們又恰好有重名的類,所以產生了這一問題。
比無法鏈接更糟糕的情況是,在運行期載入了含有重名類的程序庫。此時,“動態加載器”(dynamic loader)就遭遇了 “重名符號錯誤”(duplicate symbol error),就可能會令整個應用程序崩潰。
避免此問題的唯一辦法就是變相實現命名空間:為所有名稱都加上適當前綴。所選前綴可以與公司、應用程序或二者皆有關聯之名。比方說,假設你所在的公司叫做 Effective Widgets,那麽就可以在所有應用程序都會用到的那部分代碼中使用 EWS 作前綴,如果有些代碼只用於名為 Effective Browser 的瀏覽器項目中,那就在這部分代碼中使用 EWB 作前綴。即便加了前綴,也難保不出現命名沖突,但是其幾率會小很多。
使用 Cocoa 創建應用程序時一定要註意,Apple 宣稱其保留使用所有 “兩字母前綴”(two-letter prefix)的權利,所以你自己選用的前綴應該是三個字母的。舉個例子,加入開發者不遵循這條守則,使用 TW 這兩個字母作前綴,那麽就會出問題。iOS 5.0 SDK 發布時,包含了 Twitter 框架,此框架就使用 TW 作前綴,其中有個類叫做 TWRequest,它可以發送 HTTP 請求以調用 Twitter API。如果你所在的公司叫做 Tiny Widgets,那麽很有可能把訪問本公司 API 所用的那個類也命名為 TWRequest。
不僅是類名,應用程序中的所有名稱都應加前綴。如果要為既有類新增 “分類”(category),那麽一定要給 “分類”及“分類”中的方法加上前綴,
第15條:用前綴避免命名空間沖突