停止并重新启动计时器

时间:2017-10-17 14:31:07

标签: swift nstimer

我想停止这个计时器,然后从我停止的地方重新启动它。

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()
}

4 个答案:

答案 0 :(得分:2)

我们不会暂停/恢复Timer个实例。我们用invalidate()阻止它们。当你想重新启动时,只需创建新的计时器。

请参阅Xcode中提供的the Timer documentation

请注意,您可以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
}

答案 1 :(得分:0)

您可以在swift4中启动,停止和重置计时器

   class ViewController: UIViewController {

 var counter = 0
 var timer = Timer()
 var totalSecond = 20


@IBOutlet weak var label1: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    }





@IBAction func start_btn(_ sender: Any) {



    timer.invalidate() // just in case this button is tapped multiple times


    timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)

}






@IBAction func stop_btn(_ sender: Any) {





    do {
        self.timer.invalidate()
    }

    func timeFormatted(_ totalSeconds: Int) -> String {
        let seconds: Int = totalSeconds % 60
        return String(format: "0:%02d", seconds)
    }

    }



  @IBAction func reset_btn(_ sender: Any) {


    timer.invalidate()
   //timerAction()
    counter = 0
    label1.text = "\(counter)"


}



@objc func timerAction()


{
    counter += 1
    label1.text = "\(counter)"
}

}

答案 2 :(得分:0)

我用这个代码来做:

var timer: Timer?

func startTimer() {
    timer = .scheduledTimer(withTimeInterval: 4, repeats: false, block: { _ in
        // Do whatever
    })
}

func resetTimer() {
    timer?.invalidate()
    startTimer()
}

答案 3 :(得分:-1)

您可以将Timer声明为“弱变量”,而不是像这样的“ var”:

weak var timer: Timer?

现在,您可以通过以下方式暂停计时器:

timer?.invalidate()

要恢复:

timer?.fire()