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

如何修复iOS Swift开发中Activity Indicator不显示/卡顿问题?

问题根因
  • IBAction默认在主线程触发,你调用的DispatchQueue.global().sync为同步调度,会阻塞当前主线程,直到全局队列内的全部任务执行完成才会释放主线程控制权
  • 全局队列中提交的DispatchQueue.main.async启动指示器的UI任务,需要等待主线程空闲时才能执行,此时主线程被sync阻塞,直到抛硬币计算完成后,「启动指示器」和「停止指示器」两个UI任务会几乎同时执行,因此看不到加载动画
修复方案

核心修改

将DispatchQueue.global().sync替换为DispatchQueue.global().async,异步调度不会阻塞主线程,启动动画的UI任务可以及时执行。

可选优化

  • 添加输入值合法性、上限校验,避免用户输入过大数值导致计算耗时过长
  • 使用[weak self]避免闭包循环引用风险
  • 变量命名调整为Swift规范的小驼峰格式,避免和类型名混淆
  • 确认UIActivityIndicatorView的hidesWhenStopped属性设置为true,停止动画后自动隐藏

修复后参考代码

@IBOutlet weak var inputTextField: UITextField!
@IBOutlet weak var headsLabel: UILabel!
@IBOutlet weak var workingIndicator: UIActivityIndicatorView!

@IBAction func toss(_ sender: Any) {
    // 收起键盘避免重复触发
    inputTextField.resignFirstResponder()
    
    DispatchQueue.global().async { [weak self] in
        guard let self = self else { return }
        
        func integer(from textField: UITextField) -> Int {
            guard let text = textField.text, let number = Int(text), number > 0 else {
                return 0
            }
            // 可根据需要调整上限值
            return min(number, 1000000)
        }
        
        let input = integer(from: self.inputTextField)
        var runningTotal = 0
        
        // 主线程启动加载动画
        DispatchQueue.main.async {
            self.workingIndicator.startAnimating()
        }
        
        // 执行抛硬币计算
        for _ in 0..<input {
            if Int.random(in: 0...1) == 1 {
                runningTotal += 1
            }
        }

        // 主线程更新结果、停止动画
        DispatchQueue.main.async {
            self.headsLabel.text = String(runningTotal)
            self.workingIndicator.stopAnimating()
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:27:00