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

如何为UIViewController扩展支持异步等待的简易弹窗方法?

如何为UIViewController扩展支持异步等待的简易弹窗方法?

兄弟,我太懂你想要的效果了——就是能像写同步代码一样,弹个提示框等用户点完确定,再接着执行后面的异步逻辑对吧?你之前的代码报错主要是踩了两个小坑:UIAlertAction的按钮回调是同步闭包,不能直接套async逻辑,而且你用了两个没必要的continuation。咱们来把代码改对:

先上可以直接用的扩展代码:

extension UIViewController {
    /// 🔔 注意:仅开发调试用!生产环境谨慎使用,continuation处理不当容易引发内存泄漏
    func simpleAlert(message: String) async {
        // 用withCheckedContinuation挂起当前异步任务,直到用户点击按钮
        await withCheckedContinuation { continuation in
            let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
            
            // 给弹窗加确定按钮,点击时恢复挂起的任务
            let confirmAction = UIAlertAction(title: "Understood", style: .default) { [weak self] _ in
                self?.dismiss(animated: true) {
                    // 用户点击按钮后,通知continuation恢复任务
                    continuation.resume()
                }
            }
            alert.addAction(confirmAction)
            
            // 展示弹窗
            present(alert, animated: true)
        }
    }
}

代码逻辑说明:

  • 整个方法只需要一个withCheckedContinuation:它的作用就是把当前的异步任务挂起来,直到我们手动调用continuation.resume()
  • 按钮的回调是同步闭包,这里完全不需要写async逻辑,只需要在用户点击时触发resume(),让挂起的代码继续往下走
  • 加[weak self]是为了避免弹窗强引用ViewController导致内存泄漏,哪怕是调试用,尽量规范点总没错
  • 弹窗展示完成不需要额外的resume操作,因为我们要等的是用户的点击动作,不是弹窗弹出来的瞬间

调用方式完全符合你的预期:

await simpleAlert(message: "Let's proceed..")
await comms.sendInfo()
await simpleAlert(message: "Successful! Next step?")
await some.process()

再说说你原来代码的错误点:

  1. 你在UIAlertAction的handler里写了async闭包,但UIAlertAction的初始化要求handler是(UIAlertAction) -> Void的同步类型,不能是async函数,这就是编译器报“Invalid conversion from 'async' function”的原因
  2. 你用了两个withCheckedContinuation,其实完全没必要——我们要等的是用户点击按钮的动作,不是弹窗展示完成的事件

最后再提醒一句:这个方法只适合开发调试时快速实现需求,生产环境如果要做异步弹窗,建议用更安全的方案(比如Combine框架或者自定义回调),避免continuation带来的内存泄漏风险。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 08:19:49