如何在Swift中使用Objective-C enum [duplicate]

时间:2022-06-01 20:56:25

This question already has an answer here:

这个问题已经有了答案:

I have 2 enum definition in Objective-C file and Swift file.

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

Japanese.h

Japanese.h

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

US.swift

US.swift

enum USFoodType {
  case HUMBERGER;
  case STEAK;
}

as we know, I can use Objective-C enum like following;

我们知道,我可以使用Objective-C enum;

Japanese.m

Japanese.m

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

But I can not use Objective-C enum in Swift file like following;

但是我不能像下面这样在Swift文件中使用Objective-C enum;

  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'

    }
  }

Is this a bug of Swift? And how can I use Objective-C (C) enum in Swift file?

这是Swift的bug吗?如何在Swift文件中使用Objective-C (C) enum ?

2 个解决方案

#1


49  

I think this is a bug because Swift should define == for C enums or an "to Int" conversion but it doesn't.

我认为这是一个错误,因为Swift应该为C枚举或“to Int”转换定义== =,但事实并非如此。

The simplest workaround is redefining your C enum as:

最简单的解决方法是将您的C枚举重新定义为:

typedef NS_ENUM(NSUInteger, JapaneseFoodType) {
    JapaneseFoodType_Sushi = 1,
    JapaneseFoodType_Tempura = 2,
};

which will allow LLVM to process the enum and convert it to a Swift enum (NS_ENUM also improves your Obj-C code!).

它将允许LLVM处理enum并将其转换为Swift enum (NS_ENUM还改进了object - c代码!)

Another option is to define the equality using reinterpret hack:

另一种选择是使用reinterpretation hack来定义等式:

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

    return (leftValue == rightValue)
}

#2


13  

You should use NS_ENUM macro to make your enums Swift-compatible.

您应该使用NS_ENUM宏来使您的enum快速兼容。

Also note that your enum literals should be accessed like JapaneseFoodType._Sushi, so it's probably a good idea to remove the underscore.

还要注意,您的枚举文本应该像日式食品类型一样访问。_Sushi,因此删除下划线可能是个好主意。

#1


49  

I think this is a bug because Swift should define == for C enums or an "to Int" conversion but it doesn't.

我认为这是一个错误,因为Swift应该为C枚举或“to Int”转换定义== =,但事实并非如此。

The simplest workaround is redefining your C enum as:

最简单的解决方法是将您的C枚举重新定义为:

typedef NS_ENUM(NSUInteger, JapaneseFoodType) {
    JapaneseFoodType_Sushi = 1,
    JapaneseFoodType_Tempura = 2,
};

which will allow LLVM to process the enum and convert it to a Swift enum (NS_ENUM also improves your Obj-C code!).

它将允许LLVM处理enum并将其转换为Swift enum (NS_ENUM还改进了object - c代码!)

Another option is to define the equality using reinterpret hack:

另一种选择是使用reinterpretation hack来定义等式:

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

    return (leftValue == rightValue)
}

#2


13  

You should use NS_ENUM macro to make your enums Swift-compatible.

您应该使用NS_ENUM宏来使您的enum快速兼容。

Also note that your enum literals should be accessed like JapaneseFoodType._Sushi, so it's probably a good idea to remove the underscore.

还要注意,您的枚举文本应该像日式食品类型一样访问。_Sushi,因此删除下划线可能是个好主意。