我有一个混合项目,遇到了一个有趣的问题。
有一个在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

08-17 17:04