NSError
桥接是Swift编译器中一个有趣的野兽。一方面
N错误
来自基础框架,您的应用程序可能会使用,也可能不会使用;另一方面,实际的桥接机制需要在编译器中执行,而且正确地说,编译器应该尽可能少地了解标准库之上的“高级”库。
因此,编译器对
N错误
实际上是,相反,
Error
exposes three properties
它提供了
N错误
:
public protocol Error {
var _domain: String { get }
var _code: Int { get }
// Note: _userInfo is always an NSDictionary, but we cannot use that type here
// because the standard library cannot depend on Foundation. However, the
// underscore implies that we control all implementations of this requirement.
var _userInfo: AnyObject? { get }
// ...
}
N错误
,则具有
Swift extension which conforms to
Error
and implements those three properties
:
extension NSError : Error {
@nonobjc
public var _domain: String { return domain }
@nonobjc
public var _code: Int { return code }
@nonobjc
public var _userInfo: AnyObject? { return userInfo as NSDictionary }
// ...
}
有了这个,当你
import Foundation
任何
错误
可以转换为
N错误
反之亦然,因为两者都暴露
_domain
,
_code
和
_userInfo
(这是编译器实际用于执行桥接的内容)。
这个
CustomNSError
协议通过允许您提供
errorDomain
,
errorCode
和
errorUserInfo
,然后通过
various extensions
作为下划线版本:
public extension Error where Self : CustomNSError {
/// Default implementation for customized NSErrors.
var _domain: String { return Self.errorDomain }
/// Default implementation for customized NSErrors.
var _code: Int { return self.errorCode }
// ...
}
那么,你怎么样
EncodingError
和
DecodingError
不同的好吧,因为它们都是在标准库中定义的(无论您是否使用Foundation,标准库都存在,并且不能依赖于Foundation),所以它们通过
providing implementations of
_domain
,
_code
, and
_userInfo
directly
.
由于这两种类型都提供这些变量的直接下划线版本,因此它们不会调用非下划线版本来获取直接使用这些值的域、代码和用户信息(而不是依赖于
var _domain: String { return Self.errorDomain }
).
因此,实际上,您不能重写该行为,因为
编码错误
和
解码错误
已提供此信息。相反,如果您想提供不同的代码/域/用户信息字典,则需要编写一个函数,该函数采用
编码错误
/
解码错误
并返回您自己的
N错误
,或类似。