如何阻止NSTimer?

时间:2015-10-17 10:45:59

标签: ios multithreading swift timer 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 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{........ }
    }

如果计时器结束,则触发该方法,参见selector:

         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上。定时器正确无效,然后: 在控制台中,我读取'timer1 started',并且在按下resetButton时我没有读到'timer ended'。

但是留在这个viewcontroller(settingsVC)不是我的应用程序的流程。 当执行perform segue行并且用户'返回'到viewcontroller(settingsVC)时,当用户按下resetButton时,定时器不会失效: 在控制台中,我读到'timer1 started',当按下resetButton时,我会读取'timer ended'。

当用户“退出”视图控制器并返回重置计时器时,我应该如何停止计时器?

非常感谢帮助!提前致谢

2 个答案:

答案 0 :(得分:1)

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

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