Использование Swift 3 Остановка запланированного таймера Таймер продолжит стрельбу, даже если таймер равен нулю

Мы вызываем функцию startTimer для запуска таймера. Когда мы хотели остановить это, мы вызываем функцию stopTimerTest, но после того, как мы вызвали функцию stopTimer, timerTestAction продолжает стрелять. Чтобы проверить состояние таймера, мы использовали печать и печать в timerActionTest, возвращает nil.

var timerTest: Timer? = nil

func startTimer () {
    timerTest =  Timer.scheduledTimer(
        timeInterval: TimeInterval(0.3),
        target      : self,
        selector    : #selector(ViewController.timerActionTest),
        userInfo    : nil,
        repeats     : true)
}

func timerActionTest() {
    print(" timer condition \(timerTest)")
}

func stopTimerTest() {
    timerTest.invalidate()
    timerTest = nil
}

Ответ 1

Попробуйте внести следующие изменения в свой код:

Во-первых, вы должны изменить способ объявления timerTest

var timerTest : Timer?

затем в startTimer перед созданием экземпляра проверьте, timerTest ли timerTest нулю

func startTimer () {
  guard timerTest == nil else { return }

  timerTest =  Timer.scheduledTimer(
      timeInterval: TimeInterval(0.3),
      target      : self,
      selector    : #selector(ViewController.timerActionTest),
      userInfo    : nil,
      repeats     : true)
}

Наконец, в вашем stopTimerTest вы отменяете timerTest если он не равен нулю

func stopTimerTest() {
  timerTest?.invalidate()
  timerTest = nil
}

Ответ 2

Скорее всего, вы дважды вызывали startTimer без вызова stopTimerTest. Если вы это сделаете, вы потеряете указатель на исходный таймер и никогда не сможете его аннулировать.

Типичным подходом является управление недействительностью как часть настройки:

var timerTest : Timer? = nil {
    willSet {
        timerTest?.invalidate()
    }
}

Тогда остановка только устанавливает значение nil:

func stopTimerTest() {
    timerTest = nil
}

Ответ 3

Проверьте, действительно ли вы вызываете stopTimerTest(), потому что timerTest.invalidate() правильный для остановки таймера.

func stopTimerTest() {
    print("stopTimer")
    timerTest.invalidate()
}

Ответ 4

Убедитесь, что когда вы звоните StartTimer, это nil, и если вы звоните StartTimer дважды, не вызывая StopTimer. Вы потеряете свой первоначальный указатель и не сможете его остановить.

 var timer : Timer? = nil {
        willSet {
            timer?.invalidate()
        }
    }

Таймер запуска и остановки, как...

func startTimer() {
    stopTimer()
    guard self.timer == nil else { return }
    self.timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(self.fetchData), userInfo: nil, repeats: true)
}

func stopTimer() {
    guard timer != nil else { return }
    timer?.invalidate()
    timer = nil
}