Неправильная переопределение rawValue в сборке выпуска

У меня смешанный проект, и я столкнулся с интересной проблемой. Есть перечисление, определенное в 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, заменив RawValue на String (чтобы протокол мог неявно угадать значение), делая необязательный конструктор, как в протоколе (и неявно развернутый необязательно также) - нет пути.

Я понимаю, что расширение Int enum со строкой немного странно, но почему оно перестает собираться в Release и работает абсолютно идеально в Debug?

Есть ли какой-то другой механизм обработки перечислений / классов / расширений для конфигурации выпуска?

1 ответ

Решение

Синтаксис необработанных значений для перечислений в Swift - это просто сокращение для соответствия протоколу RawRepresentable. Это легко добавить вручную, если вы хотите использовать неподдерживаемые типы в качестве необработанных значений. Источник

Я не уверен, почему это работает в отладке, потому что когда вы создаете типизированное перечисление, вы уже "соответствуете" 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, Некоторая информация здесь. Однако это изменит ваше перечисление на struct

.час

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
Другие вопросы по тегам