如何在Swift中使用Objective-C枚举

50

我在Objective-C文件和Swift文件中有两个枚举定义。

Japanese.h

typedef enum {
  JapaneseFoodType_Sushi = 1,
  JapaneseFoodType_Tempura = 2,
} JapaneseFoodType;

US.swift

enum USFoodType {
  case HUMBERGER;
  case STEAK;
}

众所周知,我可以像以下这样使用Objective-C枚举;

Japanese.m

- (void)method {
  JapaneseFoodType type1 = JapaneseFoodType_Sushi;
  JapaneseFoodType type2 = JapaneseFoodType_Tempura;
  if (type1 == type2) {// this is no problem
  }
}

但是我无法像以下这样在Swift文件中使用Objective-C枚举;

  func method() {
    var type1: USFoodType = USFoodType.HUMBERGER// no problem
    var type2: USFoodType = USFoodType.HUMBERGER// no problem
    if type1 == type2 {

    }

    var type3: JapaneseFoodType = JapaneseFoodType_Sushi// no problem
    var type4: JapaneseFoodType = JapaneseFoodType_Tempura// no problem
    if type3 == type4 {// 'JapaneseFoodType' is not convertible to 'Selector'

    }
  }

这是Swift的一个bug吗?我该如何在Swift文件中使用Objective-C(C)枚举?

2个回答

78
我认为这是一个错误,因为Swift应该对C枚举定义==或"to Int"转换,但它没有这样做。
最简单的解决方法是重新定义你的C枚举为:
typedef NS_ENUM(NSUInteger, JapaneseFoodType) {
    JapaneseFoodType_Sushi = 1,
    JapaneseFoodType_Tempura = 2,
};

这将使LLVM能够处理枚举并将其转换为Swift枚举( NS_ENUM 还可以改善您的Obj-C代码!)。

另一种选择是使用reinterpret hack定义相等性:

public func ==(lhs: JapaneseFoodType, rhs: JapaneseFoodType) -> Bool {
    var leftValue: UInt32 = reinterpretCast(lhs)
    var rightValue: UInt32 = reinterpretCast(rhs)

    return (leftValue == rightValue)
}

谢谢你的解决方案! 我将使用NS_ENUM来解决这个问题(或者等待苹果的错误修复) 我不知道我们可以像C++一样重载运算符。 - Mitsuaki Ishimoto
谢谢,我的问题已解决。 - Ramkumar chintala
1
我的Objective C枚举使用NS_ENUM定义,但是在调用枚举时仍然存在问题。 - Shamsiddin Saidov
@Sulthan 什么是 reinterpret_cast - Vyachaslav Gerchicov
@VyachaslavGerchicov 我猜这在 Swift 中已经不存在了。这是针对 Swift 1.x 的答案。现在,你可能会使用 withMemoryRebound - Sulthan

24

您应该使用 NS_ENUM 宏来使您的枚举与 Swift 兼容。

此外,请注意您的枚举字面量应该像这样访问:JapaneseFoodType.Sushi,所以最好删除下划线。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接