异步函数中UIAlertController无法正常关闭的问题求助
解决思路
核心问题定位
错误提示的本质是弹窗 Dismiss 操作未完成时,就触发了新弹窗的 Present 操作。UIAlertController的dismiss(animated:completion:)是异步执行的——即便调用了dismiss方法,界面上的弹窗不会立刻消失,必须等其动画(或非动画的收尾逻辑)完成后,才能执行新的弹窗展示操作。你之前的失败场景就是因为跳过了这个等待过程,直接触发了新弹窗。
具体修复方案
1. 用 Dismiss 的 Completion 回调控制时序
不管成功还是失败场景,都把新弹窗的展示逻辑放在原加载弹窗dismiss方法的completion闭包里,确保原弹窗完全消失后再执行后续操作:
// 假设loadingAlert是你创建的加载弹窗实例 loadingAlert.dismiss(animated: true) { [weak self] in guard let self = self else { return } let processedString = dataString.trimmingCharacters(in: .newlines) if processedString == "no valid userID" { let errorAlert = UIAlertController(title: "提示", message: "无效的用户ID", preferredStyle: .alert) errorAlert.addAction(UIAlertAction(title: "确定", style: .default)) self.present(errorAlert, animated: true) } else { let successAlert = UIAlertController(title: "成功", message: "上传完成", preferredStyle: .alert) successAlert.addAction(UIAlertAction(title: "确定", style: .default)) self.present(successAlert, animated: true) } }
2. 废弃didSet监听的方案
你之前用didSet触发弹窗关闭,但didSet只是同步执行了dismiss调用,没有等待dismiss完成就去present新弹窗,这才导致时序冲突。改用上述completion回调的方式,能严格保证操作顺序。
3. 强制UI操作在主线程执行
异步网络请求的回调默认在后台线程,必须切换到主线程处理UI操作,否则可能出现不可预期的问题:
// 网络请求回调中切换到主线程 DispatchQueue.main.async { // 这里执行弹窗的dismiss和present操作 }
4. 避免循环引用
在闭包中捕获self时,一定要用[weak self]弱引用,防止内存泄漏。
内容的提问来源于stack exchange,提问作者blendstylez
相关产品推荐
相关产品推荐

