如何停止 NSTimer?

How to stop NSTimer?

我在使不同的计时器失效方面遇到了问题。

我在 viewcontroller(settingsVC) 上有多个计时器 (NSTimer):

 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(开始)执行 segue。并且对于变量 'picked' 的每个不同值,将在相同的 class:

中启动不同的计时器
    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

   }

我使用一个按钮(重置)使计时器无效,以获得变量('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 行并让用户停留在这个 viewcontroller.The 上,计时器就会正确失效: 在控制台中,我读取了 'timer1 started' 并且在按下 resetButton 时我没有读取 'timer ended'。

但是停留在 viewcontroller(settingsVC) 上并不是我应用程序的流程。 当执行 perform segue 行并且用户 'comes back' 到 viewcontroller (settingsVC) 时,当用户按下 resetButton 时计时器不会失效: 在控制台中,我读到 'timer1 started' 并且在按下 resetButton 时我确实读到了 'timer ended'。

当用户 'exit' viewcontroller 回来重置定时器时,我应该如何停止定时器?

非常感谢您的帮助!提前致谢

如果我在任何给定时间点没有弄错的话,你只会触发一个 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。

这是因为当你的定时器无效时你的选择器不会被调用,它会在你的定时器每次触发时被调用。由于定时器是不重复的,因此选择器只被调用一次。当你按下重置按钮时,定时器实际上已经失效,你只是不知道,因为你误解了scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:方法。