在执行计算密集型任务时,我希望向用户展示活动指标。做这个的最好方式是什么?

我的任务(当然是人为设计的)持续了几秒钟:

func startThinking(howMany: Int) {
    for i in 0...howMany {
        let p:Double = Double(i)
        let _ = p / Double.pi
    }

    delegate?.finishedThinking()
}


这是在按钮点击时调用的:

@IBAction func startTap(_ sender: Any) {
    Thinker.sharedInstance.startThinking(howMany: 500000000)
    myActivity.startAnimating()
}


并在思考任务完成时停止:

func finishedThinking() {
    print ("finished thinking")
    myActivity.stopAnimating()
}


但是活动指示器没有显示。困难的思考任务阻碍了用户界面。

我试过将startAnimating放在主线程上:

DispatchQueue.main.async {
    self.myActivity.startAnimating()
}


或将困难的任务放到自己的线程上:

DispatchQueue.global().async {
    Thinker.sharedInstance.startThinking(howMany: 500000000)
}


以及我在Stack中遇到的各种其他组合。我究竟做错了什么?

最佳答案

首先,我将调用移动到开始在思想者调用之前进行动画处理,并在您不开始思考的情况下验证它是否有效。您还需要从主线程停止动画。

@IBAction func startTap(_ sender: Any) {
    myActivity.startAnimating()
    DispatchQueue.global(qos: .userInitiated).async {
        Thinker.sharedInstance.startThinking(howMany: 500000000)
    }
}

func finishedThinking() {
    DispatchQueue.main.async {
        myActivity.stopAnimating()
    }
}


我调整了几件事:


.startAnimating()调用移到第一位。因为它是从接口调用的,所以它已经在主线程上了
qos指定为.userInitiated
在主线程上运行.stopAnimating()

关于swift - 在长任务中正确使用调度来显示事件指示器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51716661/

10-14 21:09
查看更多