您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Swift Timer.scheduledTimer()不起作用

Swift Timer.scheduledTimer()不起作用

计时器不适用于后台队列(不费吹灰之力就涉及创建运行循环或在现有运行循环上手动调度它)。但是无论如何,您绝不应该从主队列之外的任何其他位置启动任何UI更新。

因此,由于您是performSegueURLSession完成关闭(在后台队列中运行)调用的,因此它实际上也viewDidLoad后台队列中运行。因此,计划计时器的尝试失败。要解决此问题,您必须手动将performSegue代码分发到主队列:

let task = URLSession.shared.dataTask(with: url!) { data, response, error in
    ...

    if isPassed != "null" {
        DispatchQueue.main.async {
            self.performSegue(withIdentifier: "gotoGame", sender: ...)
        }
    }
}

如果您不确定主队列上是否正在运行某些代码,请参阅文档。或者,您可以使用调度先决条件:

dispatchPrecondition(condition: .onQueue(.main))

这样,如果您不小心从后台队列中调用代码,它将(在调试版本中)停止应用程序。

与您当前的问题无关,但顺便说一句,为避免计时器和视图控制器之间的引用周期过长,通常需要保留对计时器的引用,以便invalidate在视图消失时可以使用它(例如,在viewDidAppear和中创建计时器)。将其删除viewDidDisappear)。否则,您可以GameViewController在将其关闭后保留它们,例如:

class GameViewController: UIViewController {

    weak var timer: Timer?

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        timer = Timer.scheduledTimer(timeInterval: 1.0, target:self, selector: #selector(setCalculationLs(_:)), userInfo: nil, repeats: true)
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        timer?.invalidate()
    }

    @objc func setCalculationLs(_ timer: Timer) {
        print("Tick")
    }
}

或在iOS 10或更高版本中,您可以在和中使用基于块的变体,并weak参考:self``invalidate``deinit

class GameViewController: UIViewController {

    weak var timer: Timer?

    override func viewDidLoad() {
        super.viewDidLoad()

        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] timer in
            self?.setCalculationLs()
        }
    }

    deinit {
        timer?.invalidate()
    }

    func setCalculationLs() {
        print("Tick")
    }

}
Swift 2022/1/1 18:16:18 有459人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶