首页 > 解决方案 > 防止接口名称在 OSX 包中公开

问题描述

我有一组用 Cocoa 用 C++ 编写的 OSX 插件包(不使用界面生成器等),并且都使用相同的自定义@interface类作为其内部框架的一部分(它继承自 NSView)。这很简单;

@interface C_CustomView : NSView
- (BOOL)performKeyEquivalent:(NSEvent*)event;
@end

@implementation C_CustomView
- (BOOL)performKeyEquivalent:(NSEvent*)event {
    [super keyDown:event];
    return YES;
}
@end

但是,当主机应用程序同时加载我的多个插件时,我会在 XCode 日志中收到同样多的警告,说明:

objc[4144]:在 <bundle 1's path> 和 <bundle 2's path> 中都实现了 Class C_CustomView。将使用两者之一。哪一个是未定义的。

我认为这只是一个警告,因为我的插件似乎可以正常工作。我怀疑这个类是作为公共符号导出的?然而,我希望这条消息消失:)

是否有一些我可以调整的 XCode 编译器设置,或者我可以添加一些额外的代码到自定义类以防止它被导出,如果这是原因的话?我是 XCode/OSX 编码的菜鸟,如果我错过了一些明显的东西,我很抱歉。

标签: xcodemacoscocoabundle

解决方案


Objective-C 运行时试图将同一个类加载C_CustomView到一个命名空间中。

命名 Objective-C 类的标准方法使用前缀:developer.apple.com

前缀是编程接口中名称的重要组成部分。它们区分软件的功能区域。通常,该软件打包在一个框架中,或者(如 Foundation 和 Application Kit 的情况)在密切相关的框架中。前缀可防止第三方开发人员定义的符号与 Apple 定义的符号之间(以及 Apple 自己的框架中的符号之间)发生冲突。

前缀具有规定的格式。它由两个或三个大写字母组成,不使用下划线或“子前缀”。</p>

前缀用于防止这种冲突。

我的建议是将重用的类提取到自己的包/框架中,然后在需要的地方导入这个框架。

此外,根据引文,在命名类时不应使用下划线。Prefix + CamelCase 是 Objective-C 的规范。

PS:不确定 Swift 的详细信息,但那里不需要前缀(假设它不共享命名空间)


推荐阅读