2017-10-17 248 views
0

我想停止此計時器,然後從停止它的位置重新啓動計時器。停止並重新啓動計時器

secondsTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(addSeconds), userInfo: nil, repeats: true) 

下面,有人建議我不應該增加在我的定時器處理程序定時器。爲什麼不?

例如,使用GCD定時器:

func countSeconds() { 

    secondsTimer = DispatchSource.makeTimerSource(queue: .main) 
    secondsTimer?.schedule(deadline: .now(), repeating: 1.0) 

    secondsTimer?.setEventHandler { [weak self] in 

     self?.addSeconds() 
    } 
} 

@objc func addSeconds() { 
    seconds += 1       
} 

func startGame() { 
    secondsTimer?.resume() 
} 

回答

0

我們不暫停/恢復Timer實例。我們用invalidate()來阻止他們。而當你想重新啓動時,只需創建新的定時器。

請參閱the Timer documentation,也可在Xcode中使用。


注意,您可以suspendresume GCD定時器,DispatchSourceTimer

var timer: DispatchSourceTimer? // note, unlike `Timer`, we have to maintain strong reference to GCD timer sources 

func createTimer() { 
    timer = DispatchSource.makeTimerSource(queue: .main) 
    timer?.schedule(deadline: .now(), repeating: 1.0) 

    timer?.setEventHandler { [weak self] in  // assuming you're referencing `self` in here, use `weak` to avoid strong reference cycles 
     // do something 
    } 

    // note, timer is not yet started; you have to call `timer?.resume()` 
} 

func startTimer() { 
    timer?.resume() 
} 

func pauseTiemr() { 
    timer?.suspend() 
} 

func stopTimer() { 
    timer?.cancel() 
    timer = nil 
} 

請注意,我不是建議,如果你想suspendresume,你應該使用GCD DispatchSourceTimer。根據需要調用invalidate並重新創建Timer非常簡單,所以請執行此操作。爲了完整起見,我僅提供此GCD信息。


順便說一句,作爲一般原則,永遠不要在計時器處理程序中增加一些計數器。這是一個常見的菜鳥錯誤。定時器不保證每次都以準確的精度觸發。總是在開始時保存一些參考時間,然後在事件處理程序中計算當前時間和開始時間之間的差異。例如,擴展我的GCD定時器示例:

func createTimer() { 
    timer = DispatchSource.makeTimerSource(queue: .main) 
    timer?.schedule(deadline: .now(), repeating: 0.1) 

    let formatter = DateComponentsFormatter() 
    formatter.unitsStyle = .positional 
    formatter.allowedUnits = [.hour, .minute, .second, .nanosecond] 
    formatter.zeroFormattingBehavior = .pad 

    timer?.setEventHandler { [weak self] in 
     guard let start = self?.start else { return } 
     let elapsed = (self?.totalElapsed ?? 0) + CACurrentMediaTime() - start 
     self?.label.text = formatter.string(from: elapsed) 
    } 
} 

var start: CFTimeInterval?   // if nil, timer not running 
var totalElapsed: CFTimeInterval? 

@objc func didTapButton(_ button: UIButton) { 
    if start == nil { 
     startTimer() 
    } else { 
     pauseTimer() 
    } 
} 

private func startTimer() { 
    start = CACurrentMediaTime() 
    timer?.resume() 
} 

private func pauseTimer() { 
    timer?.suspend() 
    totalElapsed = (totalElapsed ?? 0) + (CACurrentMediaTime() - start!) 
    start = nil 
} 
+0

而我該如何創建一個可以停止和恢復的秒計數器?非常感謝 –

+0

當你啓動一個定時器並暫停計時器時,捕獲開始時間('CACurrentMediaTime()'或'CFAbsoluteTimeGetCurrent()'),計算'CACurrentMediaTime()'或'CFAbsoluteTimeGetCurrent()'與節省了開始時間。 – Rob

+0

我不明白你能幫我用代碼嗎? –