发布版本

时间:2018-04-03 12:22:19

标签: objective-c swift enums rawrepresentable

我有一个混合项目,并遇到了一个有趣的问题。 有一个enum,在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时它没有构建,说:< rawValue' 的重新声明无效 我尝试删除了typealias,用String替换RawValue(所以协议可以隐式猜测该值),使得构造函数在协议中是可选的(并且隐式解包也可以选择) - 不用了。

我明白用字符串扩展Int枚举有点奇怪,但是为什么它在Release中停止构建并且在Debug中工作绝对完美?

是否有一些不同的机制来处理发布配置的枚举/类/扩展?

1 个答案:

答案 0 :(得分:0)

  

Swift中枚举的原始值语法“仅仅”是符合RawRepresentable协议的简写。如果您想使用其他不受支持的类型作为原始值,则可以轻松手动添加。   Source

我不确定为什么它在调试中起作用,因为当你创建一个类型枚举时,你已经符合'到RawRepresentable。因此,当您创建NS_ENUM时,它会像swift一样导入到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