Timer.scheduledTimer 未触发

Col*_*ner 2 nstimer scenekit swift

我正在尝试计算车辆在两个检查站之间经过的时间。我已经设置了以下计时器来实现这一点。

func startTimer() {
    if hasStarted == true && timerStarted == false {
        print("Timing started!")
        gameTimer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector: (#selector(activeTiming)), userInfo: nil, repeats: true)
        timerStarted = true
    }
}

@objc func activeTiming() {
    print("Active timing block")
    if(hasFinished == false) {
        gameTime = gameTime + 0.001
        print("Add time succeeded")
    } else {
        gameTimer?.invalidate()
    }
}
Run Code Online (Sandbox Code Playgroud)

预期输出如下:

Timing started!
Active timing block
Add time succeeded
Add time succeeded ... etc
Run Code Online (Sandbox Code Playgroud)

实际输出:

Timing started!
Run Code Online (Sandbox Code Playgroud)

所以看起来 startTimer 被正确调用,但计时器没有触发 activeTiming 代码块。任何建议都会非常有帮助。提前谢谢你的帮助。

Abd*_*mer 18

我也遇到了类似的问题,计时器主体没有被调用。我发现计时器是从后台线程而不是主线程调度的。将其包裹起来DispatchQueue.main.async固定它。

DispatchQueue.main.async {
    self.pingTimer = Timer.scheduledTimer(withTimeInterval: timerInterval, repeats: true, block: { [weak self] timer in
        //
        Logger.shared.log(.anyCable, .debug, "timer run")
        self?.sendPing(sender: self)
    })
}
Run Code Online (Sandbox Code Playgroud)


Vol*_*tan 8

发布此代码,因为它是我正在使用的,但我不是 Swift 专家,所以您的里程可能会有所不同!

class PerformanceTest {
    var name:           String = ""
    var tolerance:      Int64 = 0
    var lastTime:       Int64 = 0
    var thisTime:       Int64 = 0
    var delta:          Int64 = 0
    var percent:        Float = 0

    func setTolerance(vName: String, vTolerance: Int64) {
        name = vName
        tolerance = vTolerance
    }

    func reset() {
        delta = 0
        percent = Float((Float(delta) / Float(tolerance))) * 100
        //high = 0
    }

    func start() {
        lastTime = Date().toMillis()
    }

    func finish() {
        thisTime = Date().toMillis()
        let vDelta = thisTime - lastTime
        if(vDelta > delta) {
            delta = vDelta
            percent = Float((Float(delta) / Float(tolerance))) * 100
            if(delta > tolerance) {
                print("Performance Indicator: \(name) Above Tolerance" + String(format: "%3.0f", percent) + "%")
            }
        }
    }

    func display() -> String {
        //high = delta
        //print("\(vString) Tolerance: \(tolerance) Max: \(high)")
        return String(format: "%3.0f", percent) + "%  |"
    }
   }

extension Date {
    func toMillis() -> Int64! {
        return Int64(self.timeIntervalSince1970 * 1000)
    }
Run Code Online (Sandbox Code Playgroud)

用法:

var performanceDefenseLoop = PerformanceTest()
performanceDefenseLoop.setTolerance(vName:  "DefenseLoop", vTolerance: 150)

func timeToUpdateDefenses()
{
    performanceDefenseLoop.start()
    defesensesLoop()
    performanceDefenseLoop.finish()
    print("\(performanceDefenseLoop.Display())"
}
Run Code Online (Sandbox Code Playgroud)

// 重置 performanceDefenseLoop.reset()

一定要在主线程中启动定时器!

  • “确保在主线程中启动计时器”帮助了我。我一直在从不同的线程启动计时器,但计时器从未触发过。 (12认同)
  • 请确保“确保在主线程中启动计时器”粗体:P。我花了几个小时才弄清楚为什么我的计时器没有,但这最终有所帮助:D (3认同)

vac*_*ama 2

你的代码对我有用,但这不是你想要的事件计时方式,因为它Timer不是那么准确,而且你浪费了大量的计算时间(读取电池)。

相反,我建议采用以下方法:

当事件开始时,记录开始时间:

let startTime = Date()
Run Code Online (Sandbox Code Playgroud)

当事件结束时,计算经过的时间:

let elapsedTime = Date().timeIntervalSince(startTime)
Run Code Online (Sandbox Code Playgroud)

elapsedTime将以秒为单位(包括小数秒)。