发布版本中 rawValue 的重新声明无效
Invalid redeclaration of rawValue in Release build
我有一个混合项目,遇到了一个有趣的问题。
有一个枚举,定义在 obj-c
typedef NS_ENUM (NSUInteger, ABCCategory) {
ABCCategoryFirst,
ABCCategorySecond
};
接下来,有一个 swift 文件,其中定义了扩展名
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 时它没有构建,说:Invalid redeclaration of 'rawValue'
我试过删除 typealias,用 String 替换 RawValue(因此协议可以隐式猜测值),使构造函数像协议中那样可选(并且隐式解包可选) - 不行。
我明白用字符串扩展 Int 枚举有点奇怪,但为什么它在 Release 中停止构建而在 Debug 中工作绝对完美?
是否有一些不同的机制来处理 enums/classes/extensions 的发布配置?
The raw value syntax for enums in Swift is “just” a shorthand for conformance to the RawRepresentable protocol. It’s easy to add this manually if you want to use otherwise unsupported types as raw values.
Source
我不确定为什么它在调试中有效,因为当您创建类型化枚举时,您已经 'conforming' 到 RawRepresentable
。因此,当您创建 NS_ENUM
时,它会像这样导入到 swift 中:
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";
这将由 swift 像这样导入:
public struct ABCCategory : Hashable, Equatable, RawRepresentable {
public init(rawValue: String)
}
public static let first: ABCCategory
public static let second: ABCCategory
我有一个混合项目,遇到了一个有趣的问题。 有一个枚举,定义在 obj-c
typedef NS_ENUM (NSUInteger, ABCCategory) {
ABCCategoryFirst,
ABCCategorySecond
};
接下来,有一个 swift 文件,其中定义了扩展名
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 时它没有构建,说:Invalid redeclaration of 'rawValue' 我试过删除 typealias,用 String 替换 RawValue(因此协议可以隐式猜测值),使构造函数像协议中那样可选(并且隐式解包可选) - 不行。
我明白用字符串扩展 Int 枚举有点奇怪,但为什么它在 Release 中停止构建而在 Debug 中工作绝对完美?
是否有一些不同的机制来处理 enums/classes/extensions 的发布配置?
The raw value syntax for enums in Swift is “just” a shorthand for conformance to the RawRepresentable protocol. It’s easy to add this manually if you want to use otherwise unsupported types as raw values. Source
我不确定为什么它在调试中有效,因为当您创建类型化枚举时,您已经 'conforming' 到 RawRepresentable
。因此,当您创建 NS_ENUM
时,它会像这样导入到 swift 中:
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";
这将由 swift 像这样导入:
public struct ABCCategory : Hashable, Equatable, RawRepresentable {
public init(rawValue: String)
}
public static let first: ABCCategory
public static let second: ABCCategory