我有一个混合项目,遇到了一个有趣的问题。
有一个在obj-c中定义的枚举
typedef NS_ENUM (NSUInteger, ABCCategory) {
ABCCategoryFirst,
ABCCategorySecond
};
接下来,有一个快速文件,其中定义了扩展名
extension ABCCategory: RawRepresentable {
public typealias RawValue = String
public init(rawValue: RawValue) {
switch rawValue {
case "first":
self = .first
case "second":
self = .second
default:
self = .first
}
}
public var rawValue: RawValue {
get {
switch self {
case .first:
return "first"
case .second:
return "second"
}
}
}
}
一切在Debug配置中都可以正常工作,但是当我切换到Release时,它不会构建,并说:'rawValue'的无效重新声明
我试过删除typealias,用String替换RawValue(以便协议可以隐式猜测值),使构造函数与协议中一样是可选的(并且也隐式地解开了可选的内容)-不能。
我确实知道用字符串扩展Int枚举有点怪异,但是为什么它停止在Release中构建并在Debug中工作得绝对完美呢?
是否存在一些不同的机制来处理Release配置的枚举/类/扩展?
最佳答案
Swift中枚举的原始值语法是“仅”简写,以符合RawRepresentable协议。如果您想使用其他不受支持的类型作为原始值,则可以手动手动添加。
Source
我不确定为什么它可以在调试中工作,因为当您创建类型化的枚举时,您已经“符合” RawRepresentable
。因此,当您创建NS_ENUM
时,它会迅速导入:
public enum ABCCategory : UInt {
case first
case second
}
表示它已经符合
RawRepresentable
。可以通过两种方式来实现此修复,一种是在Swift中,另一种是在Objective-C中在Swift中,我们只需删除
RawRepresentable
并将rawValue
更改为stringValue
,然后将RawValue
更改为String
:extension ABCCategory {
var stringValue: String {
switch self {
case .first: return "first"
case .second: return "second"
}
}
init(_ value: String) {
switch value {
case "first":
self = .first
case "second":
self = .second
default:
self = .first
}
}
}
或者,您可以仅将Objective-C更改为使用
NS_TYPED_ENUM
。一些信息here。但是,这会将您的枚举更改为struct
。H
typedef NSString *ABCCategory NS_TYPED_ENUM;
extern ABCCategory const ABCCategoryFirst;
extern ABCCategory const ABCCategorySecond;
.m
ABCCategory const ABCCategoryFirst = @"first";
ABCCategory const ABCCategorySecond = @"second";
这将通过如下方式迅速导入:
public struct ABCCategory : Hashable, Equatable, RawRepresentable {
public init(rawValue: String)
}
public static let first: ABCCategory
public static let second: ABCCategory