Is there a way to reference a Swift enum from an Objective-C header? If you want to see Swift classes in the Objective-C header you can use
是否有方法从Objective-C头中引用Swift enum ?如果希望在Objective-C头中看到Swift类,可以使用
@objc class Foo
I don't see anything similar for enums.
我没有看到任何类似的情况。
7 个解决方案
#1
18
What you want to do is called forward declaration
. To forward declare an enum you can do:
你要做的就是提前声明。要提交enum,你可以做:
enum name;
But since the compiler won't know the size of the enum, you will only be able to use it as a pointer in your header file. Even doing this might prove problematic if you use compiler flags like -pedantic
.
但是由于编译器不知道enum的大小,所以只能在头文件中使用它作为指针。如果您使用像-pedantic这样的编译器标记,那么这样做可能会有问题。
So in short, there is no good way to do this. Your best bet is not to, and access the enum from your implementation (.m) file instead.
简而言之,没有什么好办法。最好的办法是不访问,而是从实现(.m)文件访问enum。
In your implementation file, #import
your swift bridging header file, and, without knowing more details about your problem, you could add private properties that use your enum like this:
在您的实现文件中,#导入您的swift桥接头文件,在不了解您的问题的更多细节的情况下,您可以添加使用enum的私有属性:
@interface MyObjCClassDefinedInTheHFile()
@property (nonatomic, assign) SomeSwiftEnum type;
@end
Hope this helps.
希望这个有帮助。
#2
6
typedef SWIFT_ENUM(NSInteger, MyEnum);
typedef SWIFT_ENUM(使用NSInteger MyEnum);
#3
2
In Mixed OBJC - Swift projects the best way to have enums work in both types of classes will be to define the enum in an OBJC header and not in a swift class. swift enums can't be used in OBJC header files taken from the answer here
在混合的OBJC - Swift项目中,在两种类型的类中进行枚举的最好方法是在OBJC header中定义enum,而不是在Swift类中。swift enums不能用于从这里的答案获取的OBJC头文件
#4
-1
enums are one part of the swift Objective-C communication that does not always work. The thing is that in Objective-C, the enums can just be primitive types(NSInteger
for example).
枚举是快速Objective-C通信的一部分,它并不总是有效的。在Objective-C中,枚举可以是原始类型(例如NSInteger)。
In swift
you can have enums on more types, for example like String
. Which is one of the awesome things about swift.
在swift中,可以有更多类型的枚举,例如字符串。这是斯威夫特最令人敬畏的一点。
However, these enums wont be compiled to Objective-C because there is no equivalent for them. So they will simply be ignore and not generated in this header file that xcode creates for all your swift files. This is called Objective-C generated interface header:
然而,这些enum不会被编译为Objective-C,因为它们没有等价的。因此,它们将被忽略,而不是在xcode为所有swift文件创建的头文件中生成。这被称为Objective-C生成的接口头:
This generated file contains all the classes and enums available in objective-c . You have to mark everything you want to expose in Objective-c with @objc
or make them public
. You dont need any forward declaration for them to work, if you have this.
这个生成的文件包含objective-c中的所有类和枚举。您必须将您想要在Objective-c中公开的所有内容标记为@objc,或者公开它们。如果你有这个,你不需要任何预先声明就可以让他们工作。
Hope this helps you figure out why your enum is not visible in Objc. Let me know if it worked out.
希望这能帮助您理解为什么在Objc中看不到enum。如果成功了,请告诉我。
#5
-1
As far as I can tell, raf's answer is still correct. The cleanest solution is to simply leave your enum in an Objective-C file until you no longer need to access it from an Objective-C header. I wanted to offer another possible workaround, though.
据我所知,raf的答案仍然是正确的。最干净的解决方案是将枚举保存在Objective-C文件中,直到不再需要从Objective-C头访问它。不过,我想提供另一个可能的解决方案。
In my case I am gradually rewriting a large Objective-C project in Swift, and I don't mind an imperfect workaround if it allows me to rewrite more of my code in Swift. So I've settled on simply passing the enum to Objective-C as it's raw type, Int
, or NSInteger
to Objective-C. For example:
在我的情况下,我正在迅速地重写一个大型的Objective-C项目,如果它允许我快速地重写我的代码,我不介意有一个不完美的解决方案。因此我决定简单地将enum传递给Objective-C,因为它是原始类型,Int,或NSInteger传递给Objective-C。例如:
- (void)doSomethingWithType:(NSInteger)rawType {
if (rawType == ExampleTypeWhatever) {
// Do something
} // etc...
}
When I call this method from Swift, all I have to do is pass the .rawType
, instead of the actual enum value:
当我从Swift调用这个方法时,我所要做的就是通过.rawType,而不是实际的enum值:
objcObject.doSomething(withType: ExampleType.whatever.rawValue)
This keeps things fairly simple on both sides, and it'll be easy to update once doSomethingWithType:
is eventually rewritten in Swift.
这使得两边都相当简单,而且一旦doSomethingWithType:最终被Swift重写后,就很容易更新了。
#6
-2
I just use NSInteger
as return type for both header and implementation files. And when you need to use the enum, get the enum by let yourEnum = YourEnum(rawValue: Int(enumNSInteger))
. This works for me.
我只是使用NSInteger作为头文件和实现文件的返回类型。当您需要使用enum时,通过让yourEnum = yourEnum获得enum (rawValue: Int(enumNSInteger))。这适合我。
#7
-3
You can access Swift enums in Objective-C, but only if the enum is declared with an @objc
qualifier, which means that it has to be of type Int
.
您可以在Objective-C中访问Swift枚举,但前提是枚举用@objc限定符声明,这意味着它必须是Int类型。
#1
18
What you want to do is called forward declaration
. To forward declare an enum you can do:
你要做的就是提前声明。要提交enum,你可以做:
enum name;
But since the compiler won't know the size of the enum, you will only be able to use it as a pointer in your header file. Even doing this might prove problematic if you use compiler flags like -pedantic
.
但是由于编译器不知道enum的大小,所以只能在头文件中使用它作为指针。如果您使用像-pedantic这样的编译器标记,那么这样做可能会有问题。
So in short, there is no good way to do this. Your best bet is not to, and access the enum from your implementation (.m) file instead.
简而言之,没有什么好办法。最好的办法是不访问,而是从实现(.m)文件访问enum。
In your implementation file, #import
your swift bridging header file, and, without knowing more details about your problem, you could add private properties that use your enum like this:
在您的实现文件中,#导入您的swift桥接头文件,在不了解您的问题的更多细节的情况下,您可以添加使用enum的私有属性:
@interface MyObjCClassDefinedInTheHFile()
@property (nonatomic, assign) SomeSwiftEnum type;
@end
Hope this helps.
希望这个有帮助。
#2
6
typedef SWIFT_ENUM(NSInteger, MyEnum);
typedef SWIFT_ENUM(使用NSInteger MyEnum);
#3
2
In Mixed OBJC - Swift projects the best way to have enums work in both types of classes will be to define the enum in an OBJC header and not in a swift class. swift enums can't be used in OBJC header files taken from the answer here
在混合的OBJC - Swift项目中,在两种类型的类中进行枚举的最好方法是在OBJC header中定义enum,而不是在Swift类中。swift enums不能用于从这里的答案获取的OBJC头文件
#4
-1
enums are one part of the swift Objective-C communication that does not always work. The thing is that in Objective-C, the enums can just be primitive types(NSInteger
for example).
枚举是快速Objective-C通信的一部分,它并不总是有效的。在Objective-C中,枚举可以是原始类型(例如NSInteger)。
In swift
you can have enums on more types, for example like String
. Which is one of the awesome things about swift.
在swift中,可以有更多类型的枚举,例如字符串。这是斯威夫特最令人敬畏的一点。
However, these enums wont be compiled to Objective-C because there is no equivalent for them. So they will simply be ignore and not generated in this header file that xcode creates for all your swift files. This is called Objective-C generated interface header:
然而,这些enum不会被编译为Objective-C,因为它们没有等价的。因此,它们将被忽略,而不是在xcode为所有swift文件创建的头文件中生成。这被称为Objective-C生成的接口头:
This generated file contains all the classes and enums available in objective-c . You have to mark everything you want to expose in Objective-c with @objc
or make them public
. You dont need any forward declaration for them to work, if you have this.
这个生成的文件包含objective-c中的所有类和枚举。您必须将您想要在Objective-c中公开的所有内容标记为@objc,或者公开它们。如果你有这个,你不需要任何预先声明就可以让他们工作。
Hope this helps you figure out why your enum is not visible in Objc. Let me know if it worked out.
希望这能帮助您理解为什么在Objc中看不到enum。如果成功了,请告诉我。
#5
-1
As far as I can tell, raf's answer is still correct. The cleanest solution is to simply leave your enum in an Objective-C file until you no longer need to access it from an Objective-C header. I wanted to offer another possible workaround, though.
据我所知,raf的答案仍然是正确的。最干净的解决方案是将枚举保存在Objective-C文件中,直到不再需要从Objective-C头访问它。不过,我想提供另一个可能的解决方案。
In my case I am gradually rewriting a large Objective-C project in Swift, and I don't mind an imperfect workaround if it allows me to rewrite more of my code in Swift. So I've settled on simply passing the enum to Objective-C as it's raw type, Int
, or NSInteger
to Objective-C. For example:
在我的情况下,我正在迅速地重写一个大型的Objective-C项目,如果它允许我快速地重写我的代码,我不介意有一个不完美的解决方案。因此我决定简单地将enum传递给Objective-C,因为它是原始类型,Int,或NSInteger传递给Objective-C。例如:
- (void)doSomethingWithType:(NSInteger)rawType {
if (rawType == ExampleTypeWhatever) {
// Do something
} // etc...
}
When I call this method from Swift, all I have to do is pass the .rawType
, instead of the actual enum value:
当我从Swift调用这个方法时,我所要做的就是通过.rawType,而不是实际的enum值:
objcObject.doSomething(withType: ExampleType.whatever.rawValue)
This keeps things fairly simple on both sides, and it'll be easy to update once doSomethingWithType:
is eventually rewritten in Swift.
这使得两边都相当简单,而且一旦doSomethingWithType:最终被Swift重写后,就很容易更新了。
#6
-2
I just use NSInteger
as return type for both header and implementation files. And when you need to use the enum, get the enum by let yourEnum = YourEnum(rawValue: Int(enumNSInteger))
. This works for me.
我只是使用NSInteger作为头文件和实现文件的返回类型。当您需要使用enum时,通过让yourEnum = yourEnum获得enum (rawValue: Int(enumNSInteger))。这适合我。
#7
-3
You can access Swift enums in Objective-C, but only if the enum is declared with an @objc
qualifier, which means that it has to be of type Int
.
您可以在Objective-C中访问Swift枚举,但前提是枚举用@objc限定符声明,这意味着它必须是Int类型。