2

I have 4 NSTimers objects in my app , that make requests to a rest URL every few seconds.

On clicking of a particular button I want to stop the timer so that it stops polling and on click of another button I want to resume polling.

I have tried invalidate for all timers but does not work.

NOTE: All timers are in different class and I'm trying to invalidate the timers in another class Any help will be appreciated , thank you.

class NotificationViewController:UIViewController {
    var timer:NSTimer?
    getEvents(){
    if((timer == nil)) {
        timer = NSTimer.scheduledTimerWithTimeInterval(20.0, target: self, selector: Selector("getEvents"), userInfo: nil, repeats: true)
    }
  }
}

In another class I'm doing this on click of a button

class Menu:UIViewController {

    @IBAction func buttonTapped(sender: UIButton) {
        self.notify.timer?.invalidate()
        self.notify.timer = nil
    }
}
Nirav D
  • 71,513
  • 12
  • 161
  • 183

3 Answers3

3

It seems that you are losing the original reference to the timers. One possible evil solution, is to keep the reference across the app. You can do that using struct :

struct Timers {
   static var firstTimer = NSTimer()
   static var secondTimer = NSTimer()
   static var thirdTimer = NSTimer()
   static var fourthTimer = NSTimer()
}

This way you could access the timer from anywhere in the program:

Timers.firstTimer.invalidate()
Community
  • 1
  • 1
Idan
  • 5,405
  • 7
  • 35
  • 52
  • No the timer still keeps running –  Aug 08 '16 at 07:30
  • why do you need statics??? why do you need to access the timers from anywhere in the program??? how is that related to release of timers??? it is not the solution! moreover it is antipattern in most cases – Nikita Aug 08 '16 at 07:57
  • I want to stop the timer from a different ViewController class , So i would require to access it in that ViewController –  Aug 08 '16 at 08:10
1

Try to create a separate NotificationTimer class and used its shared object all over the project like this way.

class NotificationTimer: NSObject {

    var timer1: NSTimer?
    var timer2: NSTimer?
    var timer3: NSTimer?
    var timer4: NSTimer?

    static let sharedManager = NotificationTimer()

    func getEvents(){
        print("Fired")
        if (timer1 == nil){
            timer1 = NSTimer.scheduledTimerWithTimeInterval(20.0, target: self, selector: Selector("methodYouWantToCall"), userInfo: nil, repeats: true)
        }
    }    
}

Now call this timer1 object inside any ViewController like this way.

let notificationTimer = NotificationTimer.sharedManager
notificationTimer.timer1?.invalidate()

Or call that method like this way

NotificationTimer.sharedManager().getEvents()
Nirav D
  • 71,513
  • 12
  • 161
  • 183
  • The timer fires only once. It does not repeat after 20 seconds –  Aug 08 '16 at 09:37
  • Have you changed the selector? because getEvents is the same one that initalizing the timer. – Nirav D Aug 08 '16 at 09:40
  • No I havent changed the selector, It is the same . The method is called only once , does not execute again after 20 seconds –  Aug 08 '16 at 09:47
  • I have add print statement inside method check that it is printing or not after every 20 sec. – Nirav D Aug 08 '16 at 09:49
  • My bad. I had created another class for Timer which was not firing. This works. Thank you so much! –  Aug 08 '16 at 10:11
0
  1. Cancelling the timer:

    if (timer.isValid()) { timer.invalidate() }

    timer = nil;

  2. Just debug you app and check where you are not releasing the timer.

  3. Bear in mind, that timer retains it's target, so if you want to release the target, you will need to release the timer as well, or you can write your own timer with week reference to the target.

Nikita
  • 1,811
  • 1
  • 20
  • 41