У меня проблема с отключением разных таймеров.

У меня есть несколько таймеров (NSTimer) на контроллере просмотра (settingsVC):

 class settingsVC: UIViewController {

// I use 12 timers
var timer1 = NSTimer()

// Seconds to end the timer. Set 12 timers
let timeInterval1:NSTimeInterval = 10

var timer2 = NSTimer()
let timeInterval2:NSTimeInterval = 20

var timer3 = NSTimer()
let timeInterval3:NSTimeInterval = 30

//and so on ... 12 timers
 }

С UIButton (Старт) выполняется переход. И для каждого другого значения переменной 'selected' запускается другой таймер в том же классе:

    class settingsVC: UIViewcontroller {

    let defaults = NSUserDefaults.standardUserDefaults()
    let pickerDefaultsIntegerKey = "Picker" // nsuserdefaults key

        @IBAction func start(sender: AnyObject) {

      // segue to another viewcontroller        
      performSegueWithIdentifier("timerOn", sender: self)

      if picked == 1 {

      defaults.setInteger(1, forKey: pickerDefaultsIntegerKey)

            timer1 = NSTimer.scheduledTimerWithTimeInterval(timeInterval1,
            target: self,
            selector: "timerDidEnd:",
            userInfo: nil,
            repeats: false)

       print("timer1 started")            

    } else if picked == 2 {

     defaults.setInteger(2, forKey: pickerDefaultsIntegerKey)

            timer2 = NSTimer.scheduledTimerWithTimeInterval(timeInterval2,
            target: self,
            selector: "timerDidEnd:",
            userInfo: nil,
            repeats: false)

        print("timer2 started")          

    } else if   // ....and so on{........ }
    }

Метод запускается, если таймер заканчивается, см. Селектор:

         func timerDidEnd(timer:NSTimer){

    print("timer ended")

   // do other stuff

   }

Я аннулирую таймеры с помощью кнопки (Reset) для значений из переменной ('pickerSavedSelection'), которая обновляется сохраненными значениями в NSUserdefaults:

@IBAction func reset(sender: AnyObject) {

       if let pickerSavedSelection = defaults.integerForKey(pickerDefaultsIntegerKey) as Int?

    {

        if pickerSavedSelection == 1 {

            timer1.invalidate()

        } else if pickerSavedSelection == 2 {

            timer2.invalidate()

        } else if   //...and so on{....} 
       }

Все идет хорошо, если я перекомментирую строку perform segue и просто позволю пользователю оставаться на этом контроллере представления. Таймеры будут корректно признаны недействительными, тогда: В консоли я читаю «таймер 1 запущен», и я НЕ читаю «таймер закончился» при нажатии кнопки resetButton.

Но пребывание в этом контроллере просмотра (settingsVC) НЕ является потоком моего приложения. Когда выполняется строка perform segue и пользователь «возвращается» к контроллеру представления (settingsVC), таймеры не становятся недействительными, когда пользователь нажимает кнопку resetButton: В консоли я читаю «таймер 1 запущен» и Я Читаю «таймер закончился» при нажатии кнопки resetButton.

Как мне остановить таймеры, когда пользователи «выйдут» из контроллера просмотра и вернутся, чтобы сбросить таймеры?

Помощь очень ценится! заранее спасибо

1
codeDude 17 Окт 2015 в 13:45

2 ответа

Лучший ответ

Если я не ошибаюсь в любой момент времени, вы запускаете только один NSTimer. Все ваши разные таймеры различаются только временными интервалами. Итак, я предлагаю оставить только один NSTimer и дифференцировать временной интервал. Выбрав другое значение, вы должны сначала аннулировать таймер, а затем перезапустить его с новым временным интервалом. При этом ваш reset будет значительно упрощен, и вам не нужно будет сохранять pickerSavedSelection в NSUserDefaults. Вот как я бы переписал этот код:

class settingsVC: UIViewController {
    var timer = NSTimer()

    @IBAction func start(sender: AnyObject) {

        // segue to another viewcontroller
        performSegueWithIdentifier("timerOn", sender: self)

        if picked == 1 {
            self.timer.invalidate()

            self.timer = NSTimer.scheduledTimerWithTimeInterval(10,
                target: self,
                selector: "timerDidEnd:",
                userInfo: nil,
                repeats: false)

            print("timer1 started")
        } else if picked == 2 {
            self.timer.invalidate()

            self.timer = NSTimer.scheduledTimerWithTimeInterval(20,
                target: self,
                selector: "timerDidEnd:",
                userInfo: nil,
                repeats: false)

            print("timer2 started")          

        } else if   // ....and so on{........ }
    }

    @IBAction func reset(sender: AnyObject) {
        self.timer.invalidate()
    }
}

PS: В качестве примечания я бы посоветовал вашему NSTimer начинать и останавливать из основного потока. Используйте для этого GCD.

1
Abhinav 17 Окт 2015 в 14:00

Это связано с тем, что ваш селектор не вызывается, когда ваш таймер недействителен , он вызывается каждый раз, когда ваш таймер срабатывает . Поскольку таймер не повторяется, селектор вызывается только один раз. Когда вы нажимаете кнопку сброса, таймер фактически становится недействительным, вы просто не знали, потому что неправильно поняли метод scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:.

0
kientux 17 Окт 2015 в 13:31