Resolving Swift.h and Bridging-Header.h circular references involving enums

ぐ巨炮叔叔 提交于 2019-12-08 08:43:02

问题


I have an Objective-C header that has to be used by a Swift class. However, this header has to use the Swift.h file for an enum declared in a Swift file. In other words, the setup is as follows:

MPViewController.h

#import "MyProject-Swift.h"

@interface MPViewController: UIViewController

@property (nonatomic, assign) MPSomeEnum theEnum;
...

@end

MyProject-Bridging-Header.h

...    
#import "MPViewController.h"
...

SomeEnum.swift

@objc enum MPSomeEnum: Int {
    ...
}

When compiling the code, I get three errors:

  • 'MyProject-Swift.h' file not found
  • Failed to emit precompiled header [Xcode DerivedData folder]/[...]/MyProject-Bridging-Header-swift_[...].pch for bridging header [Project folder]/MyProject-Bridging-Header.h
  • Unknown type name 'MPSomeEnum'

Am I correct to assume that this stems from the circular reference between MyProject-Swift.h and the bridging header MyProject-Bridging-Header.h? From looking at a similar question one solution is to use forward declaration. However, it doesn't seem possible to forward declare an enum, so perhaps the only way to do this is to move the enum definition to an Objective-C file altogether?


回答1:


TL&DR; As you suspected, you need to either move the enum declaration to Objective-C, or migrate the class to Swift.

Forward declarations of enums is possible in Objective-C:

@property SomeEnum someProperty;

- (void)doSomethingWithEnum:(enum SomeEnum)enumValue;

However correct Cocoa enums are typedefs to NSInteger: typedef NS_ENUM(NSInteger, MyEnum), and the enum keyword doesn't hold enough information for how much space to allocate when using it, so you'll get into all kind of compiler error when you want to use declarations like this. Thus an enum declared in Swift is not forward declarable in Objective-C.

Now, if you really want to keep the enum definition in Swift, you could use a workaround, and declare it as NSInteger in Objective-C, while providing a specialized property in Swift:

// NS_REFINED_FOR_SWIFT imports this in Swift as __theEnum
@property(nonatomic, assign) NSInteger theEnum NS_REFINED_FOR_SWIFT;

extension MPViewController {
    // we provide a wrapper around the Objective-C property
    var theEnum: MPSomeEnum {
        // this uses a forced unwrap, beware :)
        return MPSomeEnum(rawValue: theEnum)!
    }
}


来源:https://stackoverflow.com/questions/49420490/resolving-swift-h-and-bridging-header-h-circular-references-involving-enums

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!