简体   繁体   English

在版本版本中无效的原始值重新声明

[英]Invalid redeclaration of rawValue in Release build

I have a mixed project and came across an interesting issue. 我有一个混合项目,遇到了一个有趣的问题。 There's an enum, defined in obj-c 有一个在obj-c中定义的枚举

typedef NS_ENUM (NSUInteger, ABCCategory) {
  ABCCategoryFirst,
  ABCCategorySecond
};

Next, there's a swift file where an extension is defined 接下来,有一个快速文件,其中定义了扩展名

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"
      }
    }
  }
}

Everything works fine in the Debug configuration, but when I switch to Release it does not build, saying: Invalid redeclaration of 'rawValue' I've tried removing typealias, replacing RawValue with String (so the protocol could implicitly guess the value), making constructor optional as in the protocol (and implicitly unwrapped optional also) - no go. 一切在Debug配置中都可以正常工作,但是当我切换到Release时,它不会构建,并说: 无效的'rawValue'声明,我尝试删除typealias,将RawValue替换为String(这样协议可以隐式猜测值),构造函数,如协议中的可选(以及隐式解包的可选)-不行。

I do understand that extending an Int enum with string is a bit weird, but why it stops building in Release and working absolutely perfect in Debug? 我确实知道用字符串扩展Int枚举有点奇怪,但是为什么它停止在Release中构建并在Debug中工作得绝对完美呢?

Is there some different mechanism of treating enums/classes/extensions for Release configuration? 是否有一些不同的机制来处理Release配置的枚举/类/扩展?

The raw value syntax for enums in Swift is “just” a shorthand for conformance to the RawRepresentable protocol. Swift中枚举的原始值语法是“仅”简写,以符合RawRepresentable协议。 It's easy to add this manually if you want to use otherwise unsupported types as raw values. 如果您想使用其他不受支持的类型作为原始值,则可以手动手动添加。 Source 资源

I'm not sure why it works in debug because when you create a typed enum you are already 'conforming' to RawRepresentable . 我不确定为什么它可以在调试中工作,因为当您创建类型化的枚举时,您已经“符合” RawRepresentable So when you create an NS_ENUM it is imported in to swift like so: 因此,当您创建NS_ENUM它会迅速导入:

public enum ABCCategory : UInt {
    case first
    case second
}

Meaning that it already conforms to RawRepresentable . 意味着它已经符合RawRepresentable The fix can be achieved two ways, one in Swift and in Objective-C 可以通过两种方式来实现此修复,一种是在Swift中,另一种是在Objective-C中


In Swift we just remove the RawRepresentable and change rawValue to stringValue , and RawValue to String : 在斯威夫特,我们只是删除RawRepresentable和改变rawValuestringValue ,并RawValueString

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
        }
    }

}

Or you could just change the Objective-C to use NS_TYPED_ENUM . 或者,您可以将Objective-C更改为使用NS_TYPED_ENUM Some info here . 一些信息在这里 However this will change your enum to a struct 但是,这会将您的枚举更改为struct

.h 。H

typedef NSString *ABCCategory NS_TYPED_ENUM;

extern ABCCategory const ABCCategoryFirst;
extern ABCCategory const ABCCategorySecond;

.m .m

ABCCategory const ABCCategoryFirst = @"first";
ABCCategory const ABCCategorySecond = @"second";

This will be imported by swift like so: 这将通过swift导入,如下所示:

public struct ABCCategory : Hashable, Equatable, RawRepresentable {

     public init(rawValue: String)
}

public static let first: ABCCategory
public static let second: ABCCategory

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

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