NSErrorDomain + NS_ERROR_ENUM делает поиск типов неоднозначным.Зачем? - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть ошибка, которая раньше выглядела так в Objective-C

NSString * const JKConfigurationErrorDomain;
typedef NS_ENUM(NSInteger, JKConfigurationCode) {
    JKConfigurationCodeUnknown,
    JKConfigurationCodeSomethingBad,
    JKConfigurationCodeParsing,
};

Теперь, это уродливо использовать в Swift.Но начиная со Swift 4, мы можем использовать NSErrorDomain и NS_ERROR_ENUM, чтобы сделать импортированную ошибку намного приятнее в Swift:

NSErrorDomain const JKConfigurationErrorDomain;
typedef NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationCode) {
    JKConfigurationCodeUnknown,
    JKConfigurationErrorSomethingBad,
    JKConfigurationErrorParsing,
};

Это означает, что теперь я могу делать что-то в Swift какэто:

if let myError = error as? JKConfigurationError, myError.code = .somethingBad {
    // handle it
}

вместо того, чтобы приводить error к NSError, затем проверять его .domain, затем смотреть на .code, который является целым числом, и т. д.

Все идет нормально.Но моя библиотека называется JKConfiguration, и там уже есть объект JKConfiguration (центральная часть библиотеки), и как только я начинаю использовать JKConfiguration в любом месте кода библиотеки, я получаю ошибку:

«JKConfiguration» неоднозначен для поиска типов в этом контексте

Я не понимаю, почему?Что делает NSErrorDomain или NS_ERROR_ENUM таким образом, что поиск типов становится неоднозначным и как я могу это исправить?

Что я уже пробовал:

  • использовать NS_SWIFT_NAME на NS_ERROR_ENUM typedef и переименуйте его в другое.Глядя на сгенерированный заголовок Swift, переименование работает, но не решает проблему
  • Измените имя домена ошибки (и, следовательно, сгенерированного типа ошибки в Swift).Кажется, работает в соответствии с сгенерированным заголовком Swift, но проблема все еще сохраняется.Почему это так?

1 Ответ

0 голосов
/ 29 ноября 2018

Проблема не в том, как я изначально думал, в названии домена ошибок.И это не проблема с именем библиотеки.Это проблема с именем enum-ошибки в приведенном выше примере: JKConfigurationCode.

То, что компилятор делает для случаев перечисления NS_ERROR_ENUM, является двойным:

  • использует имя перечисления и удаляет этот префикс из всех дел перечисления перед импортом их в swift
  • создайте перечисление с указанным именем для хранения этих дел. Если имя заканчивается на Code, удалите этот суффикс.

Так что последняя часть - это проблема.Это означает, что NS_ERROR_ENUM(AnyDomainName, JKConfigurationCode) генерирует перечисление в Swift для хранения кодов ошибок с префиксом имени JKConfiguration (без кода).Но этот тип уже существует в моем примере, что приводит к неоднозначности.

Таким образом, решение состоит в том, чтобы изменить

NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationCode)

на

NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationSomethingCode)

или аналогичное.Не забудьте обновить все префиксы ваших перечислений, так как кажется, что компилятор не найдет их, если префиксы не совпадают с именем перечисления.

Почему NS_SWIFT_NAME не работает для переименования enum? Насколько я могу судить, NS_SWIFT_NAME вызывает переименование типа, но не случаев.Это приводит к тому, что для кода ошибки генерируется пустой тип (в этом случае Swift выбирает структуру), поскольку Swift, похоже, не находит случаев.И оригинальный контейнер для перечислений по-прежнему имеет оскорбительное имя.

...