首页 > 代码库 > 第15条:用前缀避免命名空间冲突
第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条:用前缀避免命名空间冲突