2017-10-17 3 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()으로 그 (것)들을 멈춘다. 그리고 당신이 그것을 다시 시작하고 싶을 때, 그냥 새로운 타이머를 만드십시오.

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 
} 

나는 제안하고 있지 않다, 유의하시기 바랍니다 당신은 당신이 GCD DispatchSourceTimer 사용해야 suspendresume를 원하는 경우. 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

코드로 나를 도울 수 있습니까? –

관련 문제