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

Ios 如何使Obj-C库全局可重命名(每个类/导出的符号)?,ios,objective-c,c,linker,Ios,Objective C,C,Linker,在一个大型开源项目中,我们遇到了这个问题,因此这是一个很好的案例研究/示例: 我们的库实现了SVG规范 SVG规范定义为“包括”DOM和CSS规范 DOM规范需要DOM实现,但苹果拒绝在iOS上共享其DOM实现 我们必须在Objective中重新实现DOM,这样才能正确地实现SVG 但是苹果无意中/有意地在全局名称空间中放置了一些使用DOM保留名称的类。任何人都不可能用这些名字创建一个新类 我们目前的解决办法: 我们将受影响的类从“Name”重命名为“applehasconflictedThis

在一个大型开源项目中,我们遇到了这个问题,因此这是一个很好的案例研究/示例:

  • 我们的库实现了SVG规范
  • SVG规范定义为“包括”DOM和CSS规范
  • DOM规范需要DOM实现,但苹果拒绝在iOS上共享其DOM实现
  • 我们必须在Objective中重新实现DOM,这样才能正确地实现SVG
  • 但是苹果无意中/有意地在全局名称空间中放置了一些使用DOM保留名称的类。任何人都不可能用这些名字创建一个新类
  • 我们目前的解决办法:

  • 我们将受影响的类从“Name”重命名为“applehasconflictedThisingGlobalNamespaceName”。是的,这不是最有礼貌的消息,但它向新来者解释了为什么我们不得不偏离规范 有了iOS8,苹果又一次做到了这一点,并添加了更多关于这个问题的类,包括“评论”。(苹果?真的吗?哦,来吧,伙计们!在你向全球空间发送垃圾邮件之前先想想!)。这越来越难解决


    正常的解决方案:由于C/ObjC没有名称空间(sob!),所以我们会给每个类加前缀。SVG规范有一个官方前缀“SVG”,我们使用它。对于非规范类,我们有一个较长的前缀,这可能是我们的开源项目所独有的

    但是对于DOM,我们包括我们自己的DOM实现,开发人员的项目可能有不同的、专有的DOM实现。这里很难找到合适的前缀。苹果已经在Obj-C平台上保留了“DOM”作为前缀

    如果我们使用前缀“SVGKitDOM”,这将是最小的正确前缀名,这将使DOM(!)中类名的长度增加三倍,并且常常使代码无法读取。这也违背了苹果公司对2-3个字母前缀的偏好


    该项目是开源的,所以从技术上讲:任何人都可以将源代码全局重命名为他们想要的任何内容。但这对人们来说是一个巨大的痛苦

    我一直在考虑聪明的宏操作解决方案,例如定义可选的前缀DOM/可选的前缀SVGKitDOM/。等,它允许用户使用所需的前缀一步快速重建整个DOM和相关的SVG库

    …但这似乎仍然容易出错和混乱。这将使新提交成为一个骑士:我们必须教育每个提交者如何在每个类名中使用宏(如果这对ObjC有效的话)

    一定有更简单的方法?名称空间冲突已经成为一个问题30多年了:)


    注意:这是Objective-C,所以它是C的超集,但链接过程不是超集-例如,苹果禁止所有人动态链接。因此,我们需要一个静态的解决方案:(.

    也许,您可以使用不常提到的
    @compatibility\u alias
    属性,如下所示:

    文件:PrefixedHeader.h

    @interface my_longly_prefixed_ClassThatDoesSomething : NSObject
    @end
    
    文件:ConvenienceHeader.h

    @compatibility_alias ClassThatDoesSomething my_longly_prefixed_ClassThatDoesSomething
    
    如果用户有自己专有的DOM实现,则不要让他们导入便利性头,否则就导入便利性头


    这行得通吗?

    这是一个很棒的功能-谢谢!它被列为GCC,苹果现在似乎已经放弃/禁止了它(从2014年起,他们只允许苹果专有的LLVM编译器使用?),所以我不确定这是否还能用,但这是一个尝试的好主意。更新:似乎能用——苹果LLVM 3很高兴地使用@compatibility_别名构建,尽管除了这里的so.com答案外,我找不到任何关于此功能的文档:--注意,我在谷歌上只找到了4个关键字的点击率!我们将在几个sm上尝试一下所有情况下,一旦工作/失败,立即报告。
    @compatibility\u alias
    是一个稍微聪明的
    \define
    。您可以使用#define来代替。OS X中的
    注释
    结构比SVG旧,可能要追溯到1984年推出Mac时(或者苹果为经典Mac OS添加AIFF支持时),当时没有框架,所以你不能包括`而且很好。遗憾的是,在AIFF头的位置,现在不可能不包括它。而C在当时是相当新的。