You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift开发:如何让指定操作10秒未完成时终止并执行备选逻辑

实现方案

优先推荐使用苹果官方推荐的URLSession替换已经废弃的NSURLConnection接口,稳定性和可控性更好,两种实现方式如下:

方案1:使用URLSession实现(推荐)

直接给URLRequest设置timeoutInterval属性为10(单位为秒),请求超过10秒未完成会自动终止并触发错误回调,在错误分支执行你的备选逻辑即可:

let database = "https://example.com"
let databaseURL = URL(string: database)!
// 直接设置10秒超时
var databaseRequest = URLRequest(url: databaseURL, timeoutInterval: 10)
databaseRequest.httpMethod = "GET"

URLSession.shared.dataTask(with: databaseRequest) { [weak self] data, response, error in
    // 切回主线程处理UI和文件操作
    DispatchQueue.main.async {
        // 判断是否请求失败/超时/无返回数据
        guard let data = data, error == nil else {
            // 执行备选逻辑
            print("ERROR: Could not retrieve list.")
            let warningToUser = UIAlertController(title: "错误", message: "无法获取您的偏好设置,已重置为默认值,下次启动应用时会再次尝试。", preferredStyle: .alert)
            warningToUser.addAction(UIAlertAction(title: "确定", style: .default))
            self?.present(warningToUser, animated: true)
            return
        }
        // 原写入文件逻辑
        let databaseFile = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("local.txt")
        do {
            try data.write(to: databaseFile)
        } catch {
            print(error.localizedDescription)
        }
    }
}.resume()

方案2:保留原有NSURLConnection写法

如果需要兼容旧代码,直接给原有的URLRequest设置超时属性,在回调里判断错误类型即可:

let database = "https://example.com"
let databaseURL = URL(string: database)!
var databaseRequest = URLRequest(url: databaseURL)
databaseRequest.httpMethod = "GET"
databaseRequest.timeoutInterval = 10 // 设置10秒超时

NSURLConnection.sendAsynchronousRequest(databaseRequest, queue: OperationQueue.main) { [weak self] response, data, error in
    guard let data = data, error == nil else {
        // 超时或请求失败走备选逻辑
        print("ERROR: Could not retrieve list.")
        let warningToUser = UIAlertController(title: "错误", message: "无法获取您的偏好设置,已重置为默认值,下次启动应用时会再次尝试。", preferredStyle: .alert)
        warningToUser.addAction(UIAlertAction(title: "确定", style: .default))
        self?.present(warningToUser, animated: true)
        return
    }
    // 原写入文件逻辑
    let databaseFile = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("local.txt")
    do {
        try data.write(to: databaseFile)
    } catch {
        print(error.localizedDescription)
    }
}

注意事项

  • 不需要额外自己实现定时器监控超时,系统原生的timeoutInterval会自动在超时后终止请求并触发错误回调,性能更高也更准确
  • 所有UI相关操作必须放在主线程执行,URLSession的默认回调在后台线程,需要手动切到主队列,避免UI异常或崩溃
  • 回调中使用[weak self]避免循环引用,防止内存泄漏

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 05:27:02