【问题标题】:How to resolve "redefinition of enumerator" errors from separate objc frameworks如何解决来自不同 objc 框架的“重新定义枚举器”错误
【发布时间】:2012-03-22 21:13:57
【问题描述】:

AuthNet 和 PayPal 移动支付库都定义了 ENV_LIVE 枚举器。这会导致 Xcode 错误,例如:

Redefinition of enumerator 'ENV_LIVE' ...

在这种情况下,不能简单地更改依赖框架的源代码,objective-c 语法或 xcode 配置中有哪些可用的解决方法?

最初:

#import "PayPal.h"
#import "AuthNet.h"
...
// AuthNet
[AuthNet authNetWithEnvironment:ENV_TEST];

// PayPal
if (STATUS_COMPLETED_SUCCESS == [PayPal initializationStatus]) {
    [PayPal initializeWithAppID:@"APP-XXX" forEnvironment:ENV_SANDBOX];
}

更新(这是我根据正确答案最终使用的解决方法):

#import "PayPal.h"
@class AuthNet;
#import "AuthNetWorkaround.h"
...
[AuthNet authNetWithEnvironment:AUTHNET_ENV_TEST];

extern const int AUTHNET_ENV_LIVE;
extern const int AUTHNET_ENV_TEST;

@interface AuthNetWorkaround : NSObject

@end

#import "AuthNetWorkaround.h"
#import "AuthNet.h"

@implementation AuthNetWorkaround

const int AUTHNET_ENV_LIVE = ENV_LIVE;
const int AUTHNET_ENV_TEST = ENV_TEST;

@end

【问题讨论】:

  • 在同一个 .m 文件中包含两个框架的标头时是否看到错误?
  • 是的,在同一个文件中 - appdelegate - 我实际上需要初始化这两个库并连接到 live 或 prod 服务器。

标签: objective-c paypal xcode4.2


【解决方案1】:

发生这种情况是因为两个包含都发生在同一个编译单元中。您可以通过将包含其中一个枚举移动到一个单独的编译单元来解决此问题,但代价是使该枚举器的值成为非编译时常量(实际上,它们成为全局变量)。

在 pp_workaround.h 中:

extern const int PAYPAL_ENV_LIVE;

在 pp_workaround.m 中:

#import "PayPal.h" // I'm completely making up the name of PayPal's header
// The import of "AuthNet.h" is missing

const int PAYPAL_ENV_LIVE = ENV_LIVE;

现在您可以使用"pp_workaround.h" 代替"PayPal.h",并使用PAYPAL_ENV_LIVE 代替ENV_LIVE。并非一切都一样,但编译时错误应该消失了。

编辑如果您的代码只允许您在 .m 文件中导入冲突的标头,您可以通过将连接代码包装在额外的抽象层中来解决问题(而不是解决问题)你自己的,像这样:

在paypal_init.h中:

extern void connect_paypal();

在 paypal_init.m 中:

#import "PayPal.h"
#import "paypal_init.h"

void connect_paypal() {
    // Use ENV_LIVE from PayPal.h here
}

在 authnet_init.h 中:

extern void connect_authnet();

在 authnet_init.m 中:

#import "AuthNet.h"
#import "authnet_init.h"

void connect_authnet() {
    // Use ENV_LIVE from AuthNet.h here
}

在您的主文件中:

#import "authnet_init.h"
#import "paypal_init.h"

void init() {
    connect_paypal();
    connect_authnet();
}

【讨论】:

  • 当你说“并非一切都会一样”时,你在暗示什么?我应该注意什么?
  • @pulkitsinghal 几个 C 结构需要编译时常量。例如,如果您需要声明一个数组int vals[ENV_MAX],标准要求ENV_MAX 是一个编译时常量。不过,编译器总是会告诉你有东西坏了,所以如果一切都编译好了,你会没事的。
  • 非常感谢您保留这张光盘。去...我听从了外部建议,遇到了Undefined symbols for architecture i386: "_OBJC_CLASS_$_AuthNet", referenced from: objc-class-ref in Shoppin_PalAppDelegate.o objc-class-ref in CardProcessingUtils.o (maybe you meant: _OBJC_CLASS_$_AuthNetWorkaround)
  • 顺便说一句,我决定将 authnet 的东西放在 paypal 的东西上
  • @pulkitsinghal 看起来您没有将 AuthNet 库正确添加到您的项目中。如果您在 Google 上搜索“架构 i386 的未定义符号”,您将看到有关如何解决此链接问题的多个建议; here 是一个。
【解决方案2】:

我刚刚遇到了这个错误,构建前的清理为我解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 2015-08-12
    相关资源
    最近更新 更多