简体   繁体   English

使用 Swift 枚举时,Objective-C 方法在 Swift 中不可见

[英]Objective-C method not visible in Swift when using Swift Enum

I have a method that uses a forward declaration of a Swift enum.我有一个使用 Swift 枚举的前向声明的方法。 Whenever I do this my method isn't visible in other Swift classes.每当我这样做时,我的方法在其他 Swift 类中不可见。 Yet if I do a forward declaration for a class it is visible in Swift.然而,如果我对 class 进行前向声明,它在 Swift 中是可见的。 Why is it not visible for an enum and how can I get around this?为什么枚举不可见,我该如何解决?

// Objective-C Header file 

@class ViewController;
typedef NS_ENUM(NSInteger, MyEnumType);

@interface ObjcViewController : UIViewController
- (void)doThis: (enum MyEnumType)type;
- (void)grabTheClass: (ViewController *)mySwiftClass;
- (void)doSomethingElse;
@end


//Swift File 

@objc enum MyEnumType: Int {
    case one = 1
    case two = 2
}

@objc class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let controller = ObjcViewController()
        controller.doSomethingElse()
        controller.grabTheClass(self)
        controller.doThis(EnumType) //ERROR: This will not compile
    }
}



代码在这里

The forward declaration of the enum creates an incomplete type.枚举的前向声明创建了一个不完整的类型。 And an incomplete type has very little usefulness.不完整的类型几乎没有用处。 You can form a pointer to it, or you can call a function with a pointer to it, but that's it.您可以形成一个指向它的指针,或者您可以使用指向它的指针调用 function,但仅此而已。

Unless you complete the enum declaration with the concrete definition, you won't be able to properly consume it, neither in Objective-C, nor Swift.除非您使用具体定义完成枚举声明,否则您将无法正确使用它,无论是在 Objective-C 还是 Swift 中。

And this is why the Swift code can't see the method, because at the time the Swift compiler processes the bridging header (and this happens before any Swift code is processed), the enum is not yet materialised, thus is excluded from the bridged interface due to being an incomplete type. And this is why the Swift code can't see the method, because at the time the Swift compiler processes the bridging header (and this happens before any Swift code is processed), the enum is not yet materialised, thus is excluded from the bridged接口由于是不完整的类型。

If you add a method that takes a pointer to the enum:如果您添加一个采用指向枚举的指针的方法:

- (void)doThisWithPointer:(enum MyEnumType *)type;

then the method will be accessible from Swift, though it will be imported as那么该方法将可以从 Swift 访问,尽管它将被导入为

func doThis(withPointer type: OpaquePointer)

which doesn't make it much more helpful either.这也不会使它更有帮助。

But if forward declarations are incomplete types, why does the @class works?但是如果前向声明是不完整的类型,为什么@class有效? Its because in Objective-C objects are passed as pointers, and pointers to incomplete types are usable at call sites (as we just saw).这是因为在 Objective-C 中,对象作为指针传递,指向不完整类型的指针可在调用站点使用(正如我们刚刚看到的)。 Thus, the method is available to Swift.因此,该方法适用于 Swift。

More, the @class statement is part of the Objective-C additions to the C language, which means the compiler can give them special treatment, like importing the method with the expected signature, instead of the OpaquePointer one.此外, @class语句是 C 语言的 Objective-C 添加的一部分,这意味着编译器可以对它们进行特殊处理,例如导入具有预期签名的方法,而不是OpaquePointer之一。 This thanks to the dynamic nature of the OOP additions over the C language.这要归功于 OOP 在 C 语言上的动态特性。

It looks like doThis is a function, but you are missing the parentheses in the call.看起来doThis是 function,但您在调用中缺少括号。 The line controller.doThis should instead read controller.doThis() controller.doThis行应该改为controller.doThis()

See if that helps.看看是否有帮助。

Somebody else claimed in another post that the Swift enum needed to be declared as public in order to be visible in Objective-C.其他人在另一篇文章中声称,需要将 Swift 枚举声明为公共,以便在 Objective-C 中可见。 I haven't verified that however.然而,我还没有证实这一点。

Edit:编辑:

Okay, after some experimentation and googling, I think you have to declare your enum in Objective-C using the NSEnum macro, and that makes it available in both languages.好的,经过一些实验和谷歌搜索,我认为您必须使用NSEnum宏在 Objective-C 中声明您的枚举,这使得它可以在两种语言中使用。

I don't think Objective-C can "see" Swift Enums when they're defined in Swift.我不认为 Objective-C 可以“看到” Swift 枚举,当它们在 Swift 中定义时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM