如何使Obj-C库全局重命名(每个类/导出符号)?

时间:2014-11-14 12:00:41

标签: ios objective-c c linker

在大型开源项目上工作,我们遇到了这个问题,所以这是一个很好的案例研究/示例:

  1. 我们的库实现了SVG规范
  2. SVG Spec 定义为“包含”DOM和CSS规范
  3. DOM Spec需要DOM实现,但Apple拒绝在iOS上共享他们的DOM实现
  4. 我们不得不在ObjectiveC中重新实现DOM,因此我们可以正确实现SVG
  5. 但Apple偶然/故意将一些类放在使用DOM保留名称的全局命名空间中。任何人都不可能用这些名字创建一个新的课程
  6. 我们目前的解决方法:

    1. 我们将受影响的类重命名为例如“名称”为“AppleHasConflictedThisInGlobalNameSpaceName”。是的,这不是最礼貌的消息,但它向新手解释了为什么我们不得不偏离规范!
    2. 使用iOS8,Apple再次完成,并添加了一些有关此问题的课程,包括“评论”。 (Apple?真的吗?哦,来吧,伙计们!在你垃圾邮件全球空间之前先想想!)。这变得越来越难以解决。


      普通解决方案:由于C / ObjC没有名称空间(sob!),我们为每个类添加前缀。 SVG Spec有一个官方前缀 - “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禁止所有人进行动态链接。所以,我们需要一个静态的解决方案:(。

1 个答案:

答案 0 :(得分:2)

也许,您可以使用不经常提到的@compatability_alias属性,如下所示:

文件:PrefixedHeader.h

@interface my_longly_prefixed_ClassThatDoesSomething : NSObject
@end

文件:ConvenienceHeader.h

@compatibility_alias ClassThatDoesSomething my_longly_prefixed_ClassThatDoesSomething

如果用户拥有自己专有的DOM实现,那么让他们不要导入方便标题,否则就这样做。

这会有用吗?