NSErrorDomain + NS_ERROR_ENUM 使类型查找不明确。为什么?

Joa*_*urz 3 objective-c swift

我有一个错误,过去在 Objective-C 中看起来像这样

NSString * const JKConfigurationErrorDomain;
typedef NS_ENUM(NSInteger, JKConfigurationCode) {
    JKConfigurationCodeUnknown,
    JKConfigurationCodeSomethingBad,
    JKConfigurationCodeParsing,
};
Run Code Online (Sandbox Code Playgroud)

现在,这很难在 Swift 中使用。但是从 Swift 4 开始,我们可以使用NSErrorDomainNS_ERROR_ENUM使 Swift 中的导入错误更好:

NSErrorDomain const JKConfigurationErrorDomain;
typedef NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationCode) {
    JKConfigurationCodeUnknown,
    JKConfigurationErrorSomethingBad,
    JKConfigurationErrorParsing,
};
Run Code Online (Sandbox Code Playgroud)

这意味着我现在可以在 Swift 中做这样的事情:

if let myError = error as? JKConfigurationError, myError.code = .somethingBad {
    // handle it
}
Run Code Online (Sandbox Code Playgroud)

而不是必须强制转换errorNSError,然后检查它.domain然后查看.code哪个是整数等。

到现在为止还挺好。但是我的库被调用JKConfiguration并且那里已经有一个JKConfiguration对象(库的中心部分),一旦我开始使用JKConfiguration库代码中的任何地方,我就会收到一个错误:

在这种情况下,“JKConfiguration”对于类型查找是不明确的

我不明白,为什么?做什么NSErrorDomainNS_ERROR_ENUM做什么使类型查找变得不明确,我该如何解决?

我已经尝试过的:

  • NS_SWIFT_NAMENS_ERROR_ENUMtypedef上使用并将其重命名为其他名称。查看生成的 Swift 标头,重命名有效,但没有解决问题
  • 更改错误域的名称(从而更改 Swift 中生成的错误类型的名称)。似乎根据生成的 Swift 标头工作,但问题仍然存在。这是为什么?

Joa*_*urz 5

正如我最初认为的那样,问题不在于错误域的名称。也不是库名的问题。这是错误枚举名称的问题,在上面的示例中:JKConfigurationCode。

编译器对 NS_ERROR_ENUM 的枚举情况所做的有两个方面:

  • 使用枚举的名称并在将它们导入 swift 之前从所有枚举案例中删除该前缀
  • 创建一个具有给定名称的枚举来保存这些案例。如果给定的名称以Code删除该后缀结尾。

所以最后一部分是问题。这意味着NS_ERROR_ENUM(AnyDomainName, JKConfigurationCode)在 Swift中生成一个枚举来保存带有名称JKConfiguration(不带代码)前缀的错误代码。但是这种类型已经存在于我的示例中,这导致了歧义。

所以解决办法是改变

NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationCode)
Run Code Online (Sandbox Code Playgroud)

NS_ERROR_ENUM(JKConfigurationErrorDomain, JKConfigurationSomethingCode)
Run Code Online (Sandbox Code Playgroud)

或者类似的。不要忘记更新枚举案例的所有前缀,因为如果前缀与枚举名称不匹配,编译器似乎找不到它们。

为什么 NS_SWIFT_NAME 不能重命名枚举? 我能说的最好的是, NS_SWIFT_NAME 导致类型被重命名,但不是案例。这会导致为错误代码生成一个空类型(在这种情况下 Swift 选择一个结构),因为 Swift 似乎没有找到这些案例。并且枚举案例的原始容器仍然具有违规名称。

  • 出色的侦探工作,感谢您解释得如此清楚。 (2认同)