swiftyboi
swiftyboi

Reputation: 3221

Why can't I stop NSTimer?

I have completely hit a wall. This should not be as difficult as it has been for me. I start my timer, no problem. When I try to stop it, it keeps going. I've tried invalidating in the usual way, but it is basically ignored for some reason. What am I doing wrong?!

Code:

var random = CGFloat()

var timer = NSTimer()

var counter = 0 as CGFloat

func startCountdown() {

    counter = 0

    random = CGFloat(Float(arc4random()) / Float(UINT32_MAX) * 5)

    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounter"), userInfo: nil, repeats: true)

}

func stopCountdown() {

    timer.invalidate()

}

@IBAction func startGame(sender: AnyObject) {

    startCountdown()

}

func updateCounter() {

    counter++

    println("counter: \(counter) random: \(random)")

}

@IBAction func tapped(sender: AnyObject) {

    if counter >= random {

        println("Good job")

        stopCountdown()

        //startCountdown()


    } else {

        println("Game over")

    }

}

Upvotes: 0

Views: 76

Answers (2)

swiftyboi
swiftyboi

Reputation: 3221

I had my startButton starting an NSTimer while tapped started another timer at the same time. I just rearranged the app a little bit. I started the timer initially using viewDidLoad().

Upvotes: 0

Rich Tolley
Rich Tolley

Reputation: 3842

I think you have an orphan NSTimer hanging around in memory. Because NSTimers are scheduled on the run loop they aren't necessarily deallocated when you overwrite instance variables pointing to them.

What I expect is happening is that you are somehow scheduling the timer twice before the first invalidation happens. When you schedule a new timer in startCountdown() you overwrite the previous timer, but don't invalidate it. If you have somehow called startCountdown()/startGame() twice this means you have a still firing timer that your stopCountdown can't affect because the timer instance variable is now pointing at a different object.

If this is what's happening, the fix is easy - just invalidate the old timer in startCountdown() before scheduling the new one.

Upvotes: 2

Related Questions