常见协议 — Error

在 Swift 中,错误处理通过 Error 协议实现,允许开发者定义、抛出和捕获自定义错误类型。localizedDescriptionNSError 的属性,用于获取错误的本地化描述。以下是详细说明及示例:


1. Error 协议 #

  • 核心作用:任何遵循 Error 协议的类型(如 enumstruct)均可表示错误。
  • 典型用法:使用枚举定义一组错误类型。
    enum NetworkError: Error {
        case invalidURL
        case requestFailed(statusCode: Int)
        case decodingFailed
    }
    

2. 抛出与捕获错误 #

  • 抛出错误:使用 throw 关键字。
    func fetchData() throws {
        guard let url = URL(string: "https://example.com") else {
            throw NetworkError.invalidURL
        }
        // ...
    }
    
  • 捕获错误:使用 do-try-catch 结构。
    do {
        try fetchData()
    } catch NetworkError.invalidURL {
        print("URL 无效")
    } catch let NetworkError.requestFailed(code) {
        print("请求失败,状态码:\(code)")
    } catch {
        print("其他错误:\(error)")
    }
    

3. localizedDescription 属性 #

  • 来源:属于 NSError 类型,但 Swift 的 Error 可桥接到 NSError
  • 作用:提供错误的本地化描述,便于展示给用户。
  • 默认行为:若未自定义,返回错误类型的名称(如 "invalidURL")。
    do {
        try fetchData()
    } catch {
        let nsError = error as NSError
        print("错误描述:\(nsError.localizedDescription)")
        // 输出示例:The operation couldn’t be completed. (NetworkError error 0.)
    }
    

4. 自定义错误描述 #

方式一:实现 LocalizedError 协议 #

  • 关键属性

    • errorDescription: 错误的主要描述。
    • failureReason: 错误的详细原因。
    • recoverySuggestion: 恢复建议。
    enum NetworkError: Error, LocalizedError {
        case invalidURL
        case requestFailed(statusCode: Int)
    
        var errorDescription: String? {
            switch self {
            case .invalidURL:
                return "URL 格式无效"
            case .requestFailed(let code):
                return "请求失败 (状态码:\(code))"
            }
        }
    
        var failureReason: String? {
            switch self {
            case .invalidURL:
                return "请检查 URL 是否包含非法字符"
            case .requestFailed:
                return "服务器返回了错误状态码"
            }
        }
    }
    

方式二:实现 CustomNSError 协议 #

  • 自定义 NSError 的 domain、code 和 userInfo
    extension NetworkError: CustomNSError {
        static var errorDomain: String { "com.example.NetworkError" }
    
        var errorCode: Int {
            switch self {
            case .invalidURL: return 1001
            case .requestFailed: return 1002
            }
        }
    
        var errorUserInfo: [String: Any] {
            [NSLocalizedDescriptionKey: errorDescription ?? "未知错误"]
        }
    }
    

5. 获取本地化信息 #

do {
    try fetchData()
} catch {
    let nsError = error as NSError
    print("描述:\(nsError.localizedDescription)")
    print("原因:\(nsError.localizedFailureReason ?? "")")
    print("建议:\(nsError.localizedRecoverySuggestion ?? "")")
}

6. 其他相关协议 #

  • RecoverableError: 定义可恢复错误(如提供恢复选项)。
  • CustomDebugStringConvertible: 自定义调试时的错误描述(通过 debugDescription)。

总结 #

  • Error 协议:定义错误类型的基础。
  • localizedDescription:通过桥接 NSError 获取用户友好的错误描述。
  • 自定义描述:优先实现 LocalizedErrorCustomNSError 协议。
  • 最佳实践:使用枚举组织错误,结合协议提供清晰的错误信息。
本文共 1077 字,创建于 Mar 8, 2025
相关标签: Xcode, Swift