Подтвердить что ты не робот

Как использовать перечисление Objective-C в Swift

У меня есть 2 определения перечисления в файле Objective-C и файле Swift.

Japanese.h

typedef enum {
  JapaneseFoodType_Sushi = 1,
  JapaneseFoodType_Tempura = 2,
} JapaneseFoodType;

US.swift

enum USFoodType {
  case HUMBERGER;
  case STEAK;
}

как мы знаем, я могу использовать перечисление Objective-C следующим образом:

Japanese.m

- (void)method {
  JapaneseFoodType type1 = JapaneseFoodType_Sushi;
  JapaneseFoodType type2 = JapaneseFoodType_Tempura;
  if (type1 == type2) {// this is no problem
  }
}

Но я не могу использовать перечисление Objective-C в файле Swift, как показано ниже:

  func method() {
    var type1: USFoodType = USFoodType.HUMBERGER// no problem
    var type2: USFoodType = USFoodType.HUMBERGER// no problem
    if type1 == type2 {

    }

    var type3: JapaneseFoodType = JapaneseFoodType_Sushi// no problem
    var type4: JapaneseFoodType = JapaneseFoodType_Tempura// no problem
    if type3 == type4 {// 'JapaneseFoodType' is not convertible to 'Selector'

    }
  }

Это ошибка Swift? И как я могу использовать перечисление Objective-C (C) в файле Swift?

4b9b3361

Ответ 1

Я думаю, что это ошибка, потому что Swift должен определять == для перечислений C или преобразования "to Int", но это не так.

Простейшим обходным решением является переопределение вашего C-enum как:

typedef NS_ENUM(NSUInteger, JapaneseFoodType) {
    JapaneseFoodType_Sushi = 1,
    JapaneseFoodType_Tempura = 2,
};

который позволит LLVM обрабатывать перечисление и преобразовывать его в перечисление Swift (NS_ENUM также улучшает ваш код Obj-C!).

Другим вариантом является определение равенства с использованием reinterpret hack:

public func ==(lhs: JapaneseFoodType, rhs: JapaneseFoodType) -> Bool {
    var leftValue: UInt32 = reinterpretCast(lhs)
    var rightValue: UInt32 = reinterpretCast(rhs)

    return (leftValue == rightValue)
}

Ответ 2

Вы должны использовать макрос NS_ENUM, чтобы сделать ваши рекурсии Swift-совместимыми.

Также обратите внимание, что ваши литералы перечисления должны быть доступны, например, JapaneseFoodType._Sushi, поэтому, вероятно, рекомендуется удалить подчеркивание.