解决涉及枚举的 Swift.h 和 Bridging-Header.h 循环引用
Resolving Swift.h and Bridging-Header.h circular references involving enums
我有一个 Objective-C header 必须由 Swift class 使用。但是,此 header 必须将 Swift.h
文件用于 Swift 文件中声明的枚举。也就是说,设置如下:
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 {
...
}
编译代码时,出现三个错误:
- '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'
我假设这源于 MyProject-Swift.h
和桥接 header MyProject-Bridging-Header.h
之间的循环引用是否正确?从 similar question 来看,一种解决方案是使用前向声明。但是,转发声明枚举似乎是不可能的,所以也许唯一的方法是将枚举定义完全移动到 Objective-C 文件中?
TL&DR; 如您所料,您需要将枚举声明移至 Objective-C,或将 class 移至 Swift .
枚举的前向声明在 Objective-C 中是可能的:
@property SomeEnum someProperty;
- (void)doSomethingWithEnum:(enum SomeEnum)enumValue;
然而,正确的 Cocoa 枚举是 NSInteger
的类型定义:typedef NS_ENUM(NSInteger, MyEnum)
,并且 enum
关键字没有包含足够的信息 space在使用它时分配,所以当你想使用这样的声明时,你会遇到各种编译器错误。因此,在 Swift
中声明的枚举在 Objective-C 中不可向前声明。
现在,如果您真的想保留 Swift 中的枚举定义,您可以使用变通方法,将其声明为 Objective-C 中的 NSInteger
,同时提供专门的 属性 在 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)!
}
}
我有一个 Objective-C header 必须由 Swift class 使用。但是,此 header 必须将 Swift.h
文件用于 Swift 文件中声明的枚举。也就是说,设置如下:
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 {
...
}
编译代码时,出现三个错误:
- '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'
我假设这源于 MyProject-Swift.h
和桥接 header MyProject-Bridging-Header.h
之间的循环引用是否正确?从 similar question 来看,一种解决方案是使用前向声明。但是,转发声明枚举似乎是不可能的,所以也许唯一的方法是将枚举定义完全移动到 Objective-C 文件中?
TL&DR; 如您所料,您需要将枚举声明移至 Objective-C,或将 class 移至 Swift .
枚举的前向声明在 Objective-C 中是可能的:
@property SomeEnum someProperty;
- (void)doSomethingWithEnum:(enum SomeEnum)enumValue;
然而,正确的 Cocoa 枚举是 NSInteger
的类型定义:typedef NS_ENUM(NSInteger, MyEnum)
,并且 enum
关键字没有包含足够的信息 space在使用它时分配,所以当你想使用这样的声明时,你会遇到各种编译器错误。因此,在 Swift
中声明的枚举在 Objective-C 中不可向前声明。
现在,如果您真的想保留 Swift 中的枚举定义,您可以使用变通方法,将其声明为 Objective-C 中的 NSInteger
,同时提供专门的 属性 在 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)!
}
}