15、用前缀避免命名空间冲突

因为OC没有命名空间这一机制,所以改用为所有名称都加上适当的前缀来变相实现命名空间(比如:你的公司叫Effective Widgets,那么可以使用EWS做前缀),减少重名几率。

​ 使用Cocoa创建应用程序时要注意了,Apple宣称其保留使用所有两个字母前缀的权利,所以你自己选用的前缀应该时三个字母的。(如果现在系统类里没有,保不准之后更新会出现跟你同名的两个字母前缀的系统类)

​ 不仅时类名,程序中所有名称都应加上前缀,如要为既有类新增分类,则一定要给分类分类中的方法加上前缀。还有个可能会忽视的容易引发命名冲突的地方,就是类的实现文件中所用的纯C函数全局变量,在编译好的目标文件中,这些名称都是“顶级符号”。如:

// 应加前缀:EOCSoundPlayerCompletion (项目前缀 + 类前缀 + 方法名)
void completion(SystemSoundID ssID, void *clientData) {
  // 触发代理,实现某些方法
}
- (void)playSound {
  // 播放声音
  AudioServiceAddSystemSoundCompletion(
    _systemSoundID,
      NULL,
      NULL,
      completion, // 播放完后回调
      (__bridge void *)self
  );
  AudioServicesPlaySystemSound(_systemSoundID);
}

​ 这段代码看上去很正常,不过再看看该类目标文件中的符号表(symbol table),就会发现问题了:

播放音频回调符号表

​ 虽说completion函数是在实现文件里定义的,并没有声明于头文件中,不过它仍是顶级符号。此时若在别处创建一个名为completion的函数,则会于链接时报错(重复符号错误):

duplicate symbol _completion in:
    build/EOCSoundPlayer.o
  build/EOCAnotherClass.o

​ 如果将代码发布为程序库供他人使用,就更糟糕了。使用此程序库的开发者再无法创建名为completion的函数了。

​ 若自己编写程序库提供给他人使用,其中用到别人的三方库时,应该为其加上自己的前缀。因为别人可能也用到了这个库;亦或者:别人要用A版本,而你用的B版本,那么他必须自己再引入一份;更有甚:别人还用了另一个三方库(里也同样用了你用的三方库),此时如果都没加前缀,那么程序依然会出现重复符号错误。

制作库时为使用到的三方库加前缀

要点:

  • 选择与你的公司、应用程序或二者皆有关联之名称作为类名的前缀,并在所有代码中均使用这一前缀

  • 若自己所开发的程序库中用到了第三方库,则应为其中的名称加上前缀

Last updated

Was this helpful?