ios开发方向——swift错误处理:do/try/catch、Result、throws

1. throws:标记「可能出错」的函数

使用场景 :当一个函数 / 方法执行时可能失败(如网络请求、文件操作、数据解析),需要把错误传递给调用者 处理时,用 throws 标记函数。

Swift 复制代码
// 1. 先定义错误类型(遵循 Error 协议)
enum NetworkError: Error {
    case invalidURL      // 无效 URL
    case noData          // 无数据返回
    case decodingFailed  // 数据解析失败
}

// 2. 用 throws 标记「可能出错」的函数
func fetchUserInfo(from urlString: String) throws -> [String: Any] {
    // 模拟:检查 URL 是否有效
    guard let url = URL(string: urlString) else {
        // 出错时:用 throw 抛出错误(函数会立即终止,错误传递给调用者)
        throw NetworkError.invalidURL
    }
    
    // 模拟:网络请求获取数据
    let fakeData: Data? = nil // 假设请求失败,无数据
    guard let data = fakeData else {
        throw NetworkError.noData
    }
    
    // 模拟:解析数据
    guard let json = try? JSONSerialization.jsonObject(with: data),
          let userInfo = json as? [String: Any] else {
        throw NetworkError.decodingFailed
    }
    
    // 成功时:返回结果
    return userInfo
}

2. do/try/catch:立即捕获并处理错误

使用场景 :当你调用一个 throws 函数,想要就地处理错误 (比如给用户弹提示、回退操作)时,用 do/try/catch 包裹调用。

Swift 复制代码
func showUserProfile() {
    let urlString = "https://api.example.com/user"
    
    // do 块:写可能出错的代码
    do {
        // try:标记调用 throws 函数的位置
        let userInfo = try fetchUserInfo(from: urlString)
        // 成功路径:更新 UI
        print("获取用户信息成功:\(userInfo)")
    } 
    // catch 块:捕获并处理错误(可以捕获特定错误,也可以捕获所有错误)
    catch NetworkError.invalidURL {
        print("错误:URL 无效,请检查地址")
    } catch NetworkError.noData {
        print("错误:网络请求无数据,请稍后重试")
    } catch NetworkError.decodingFailed {
        print("错误:数据解析失败")
    } catch {
        // 捕获其他未定义的错误(用 error 变量访问具体错误)
        print("未知错误:\(error)")
    }
}

// 调用测试
showUserProfile()

3. Result:封装「成功 / 失败」的结果(尤其适合异步)

使用场景

  • 异步操作 (如网络请求、耗时计算):因为异步函数没法直接用 throws 传递错误,Result 可以把「成功值」和「错误」封装成一个枚举,通过回调传递。
  • 需要延迟处理错误把错误当值传递 / 存储时。
Swift 复制代码
// 1. 模拟异步网络请求函数(用 Result 作为回调参数)
func asyncFetchUserInfo(
    from urlString: String,
    completion: @escaping (Result<[String: Any], NetworkError>) -> Void
) {
    // 模拟异步延迟(比如网络请求耗时)
    DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
        // 检查 URL
        guard let _ = URL(string: urlString) else {
            // 失败时:回调 .failure(错误)
            completion(.failure(.invalidURL))
            return
        }
        
        // 模拟成功返回数据
        let fakeUserInfo: [String: Any] = ["name": "张三", "age": 20]
        // 成功时:回调 .success(值)
        completion(.success(fakeUserInfo))
    }
}

// 2. 调用异步函数,用 switch 处理 Result
func loadUserAsync() {
    print("开始异步请求...")
    
    asyncFetchUserInfo(from: "https://api.example.com/user") { result in
        // 用 switch 解包 Result(处理成功/失败两种情况)
        switch result {
        case .success(let userInfo):
            // 成功路径:拿到值
            print("异步请求成功:\(userInfo)")
        case .failure(let error):
            // 失败路径:拿到错误
            print("异步请求失败:\(error)")
        }
    }
}

// 调用测试
loadUserAsync()

简单对比总结

方式 核心场景 特点
throws 同步函数可能出错,需传递错误 轻量,错误直接向上传递
do/try/catch 调用 throws 函数时就地处理错误 清晰分离成功 / 失败逻辑,可捕获特定错误
Result 异步操作、需延迟 / 传递错误结果 把成功 / 失败封装成值,适合回调传递
相关推荐
LX567772 小时前
传统销售如何系统学习成为AI智能销售顾问?认证指南
人工智能·学习
网域小星球2 小时前
C 语言从 0 入门(十七)|结构体指针 + 动态内存 + 文件综合实战
c语言·开发语言·文件操作·结构体指针·动态内存·综合项目
做cv的小昊2 小时前
【TJU】应用统计学——第五周作业(3.1 假设检验的基本思想、3.2 单个正态总体参数的假设检验)
学习·线性代数·机器学习·数学建模·矩阵·概率论·tju
aq55356002 小时前
三大编程语言深度对比:C# vs 易语言 vs 汇编
开发语言·汇编·c#
独特的螺狮粉2 小时前
云隙一言:鸿蒙Flutter框架 实现的随机名言应用
开发语言·flutter·华为·架构·开源·harmonyos
光泽雨2 小时前
c# 文件编译的过程
开发语言·c#
格鸰爱童话3 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习
赤水无泪3 小时前
09 C++ 11 新增的标准
开发语言
H_老邪3 小时前
spring boot 学习之路-1.0
spring boot·后端·学习