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 异步操作、需延迟 / 传递错误结果 把成功 / 失败封装成值,适合回调传递
相关推荐
是一个Bug10 分钟前
Agent(智能体)应用 的入门学习路径
学习·机器学习
2301_8090511417 分钟前
Linux 网络编程 学习笔记
linux·网络·学习
方也_arkling1 小时前
【Java-Day08】static / final / 枚举
java·开发语言
风吹夏回1 小时前
Python 全局异常处理:从“满屏 try-except”到优雅兜底
开发语言·python
Chengbei111 小时前
一站式源码安全检测工具、云安全 / APP / 小程序源码敏感信息递归多层目录扫描AK、JWT、手机号、身份证等敏感信息
java·开发语言·安全·web安全·网络安全·系统安全·安全架构
eggcode1 小时前
【Qt学习】Linux(ARM架构)在线安装Qt6.x
linux·qt·学习·arm
llz_1121 小时前
web-第一次课后作业
java·开发语言·idea
小熊Coding1 小时前
Python爬取当当网二手图书项目实战!
开发语言·爬虫·python·beautifulsoup·requests·二手图书
秋92 小时前
Java项目运行5天左右自动宕机:系统性定位与解决方案
java·开发语言·python
xiaoshuaishuai82 小时前
C# 内存管理与资源泄漏
开发语言·c#