在处理一个大型开源项目时,我们遇到了这个问题,因此这是一个很好的案例研究/示例:
- 我们的库实现了 SVG 规范
- SVG 规范被定义为“包括”DOM 和 CSS 规范
- DOM Spec 需要 DOM 实现,但 Apple 拒绝在 iOS 上分享他们的 DOM 实现
- 我们必须在 ObjectiveC 中重新实现 DOM,才能正确实现 SVG
- 但 Apple 意外/故意将一些使用 DOM 保留名称的类放在全局命名空间中。任何人都不可能用这些名字创建一个新类(class)
我们当前的解决方法:
- 我们重命名受影响的类,例如“名称”到“AppleHasConflictedThisInGlobalNameSpaceName”。是的,这不是最礼貌的信息,但它向新手解释了为什么我们不得不偏离规范!
在 iOS8 中,Apple 再次做到了这一点,并添加了更多解决此问题的类,包括“评论”。 (Apple?真的吗?哦,来吧,伙计们!在向全局空间发送垃圾邮件之前请三思!)。这越来越难以解决。
常规解决方案:由于 C/ObjC 没有命名空间(呜呜!),我们会为每个类添加前缀。 SVG 规范有一个官方前缀——“SVG”——我们使用它。对于非规范类,我们有一个较长的前缀,这可能是我们的开源项目独有的。
但是对于 DOM,我们包含了我们自己的 DOM 实现,并且开发人员的项目可能有不同的专有 DOM 实现。在这里很难想出合理的前缀。 Apple 已经在 Obj-C 平台上保留了“DOM”作为前缀。
如果我们使用前缀“SVGKitDOM”,这将是最小的正确前缀名称,这会使 DOM 中类名的长度增加三倍(!),并且通常会使代码不可读。这也违反了 Apple 对 2-3 个字母前缀的偏好。
该项目是开源的,因此从技术上讲:任何人都可以将源代码全局重命名为他们想要的任何内容。但这对人们来说是一个巨大的痛苦。
我一直在考虑巧妙的宏化解决方法 - 例如#define OPTIONAL_PREFIX DOM/OPTIONAL_PREFIX SVGKitDOM/..etc 允许用户使用他们需要的任何前缀快速重建整个 DOM 和依赖的 SVG 库。
...但这似乎仍然容易出错和困惑。而且它会使新的提交成为噩梦:我们必须教育每个提交者如何在每个类名中使用宏(如果这甚至适用于 ObjC)。
啊!
一定有更简单的方法吗? 30 多年来,命名空间冲突一直是个问题。
注意:这是 Objective-C,所以它是 C 的超集,但链接过程不是超集 - 例如,Apple 禁止所有人进行动态链接。所以,我们需要一个静态的解决方案。
Best Answer-推荐答案 strong>
或许,你可以使用不常提及的@compatability_alias 属性,如下:
文件refixedHeader.h
@interface my_longly_prefixed_ClassThatDoesSomething : NSObject
@end
文件:ConvenienceHeader.h
@compatibility_alias ClassThatDoesSomething my_longly_prefixed_ClassThatDoesSomething
如果用户有他们自己的专有 DOM 实现,那么让他们不要导入便利 header ,否则就这样做。
这行得通吗?
关于ios - 如何使 Obj-C 库全局可重命名(每个类/导出的符号)?,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/26929576/
|