Swift Components Tour – NSTimer Management

In this lesson

Back in the Swift Components Tour app, we are talking about NSTimer, specifically how to manage existing timers in your code.

Kyle Roberts
Swift Guru at Large

Kyle's Series


Tap on time to skip ahead


Hello world! Kyle here with Brax.tv and we are deep inside the Swift Components Tour and all the way into the TextFieldsViewController. This video will be about an important thing to remember when working with NSTimers. You can see that we have an NSTimer running in the background so that we are changing the text every one second on this label. It’s a cool little waiting animation sort of thing going on. There’s sort of a gotcha that I would like to cover about NSTimer so that it can maybe save you some time in the future, if you do run into this.

An example of that one gotcha here is that when we do edit these text fields in this screen so that the label stops animating from waiting and actually shows the sum of the two text field values. When we clear one of the text fields, it should go back to animating the waiting label. Right now, it looks how we want it to. It looks how we expect it to look. That’s because of one important line here which is the invalidate method on the timer. We’re just telling our classes reference to that NSTimer to invalidate. You can see that we have it up here too because there are two situations in the logic that we would need the timer to stop running. And that’s what that method does, it just stops the timer from taking and calling whatever selector that’s attached to every interval.


What this logic says here is that if there’s a number in each text field then we will tell the timer to stop. Which will stop any of the animations here. Then we’re going to change that UILabel’s text to the sum, first in the second number in the text fields. But if there’s not a first and second number, then we’ll stop the timer and then we’ll start animating that label again. If you remember in this startAnimatingLabel method that we just set the timer to a new instance and we restart it with an interval of one pointing at that animate label method. Make sure that it does repeat. It’s important that we do stop the timer here in case an ever is running. The best way to show you why, I think, is to just get rid of it and see what happens. And I’ll explain what does happen when we see it.


Bo do do do do do


So we’re back on this screen. And we can see that the waiting label is animating beautifully. Let’s change the text so it stops animating and now says 2. I’m going to remove – we actually need to get rid of both of those validate methods right there. And now we’re going to go back to the app.


We’re back in this TextFieldViewController and the waiting label is animating how we want it to. I’m going to just put two numbers in these two text fields so that the sum does display in place of the waiting label at the top. Which is all fine and dandy. But as soon as we backspace on one of the text fields so that the text is nil, or an empty string, the waiting label starts animating but it looks a little messed up and disjointed. It’s not changing it’s text at an interval of every one second. The reason for this is that even though we may have called the startAnimating method again and reset our reference of our NSTimer to a brand new instance, which is pointing at the exact same selector with the same other parameters, but the problem is that we never told our previous timer to invalidate. We might not have a reference to it any more. It’s not getting garbage collected through arc because it’s still running in the background. We don’t have that reference anymore so we cannot tell it to stop. Our previous reference has been overwritten with a new instance and both of them are running at the same time.


Both timers are firing every one second but they’re not paying attention to each other. The first one is firing every one second, the other one is firing every one second. But they’re not lining up so that the waiting label text looks like it has kind of a limp going on. That’s the gotcha about NSTimers is that you need to call the invalidate method any time you want to stop the timer. Or any time that the timer shouldn’t be running. Even if right here, how we just want to reset the time because it’s not even running, in this situation where there’s a number in each text field. As soon as we erase this one number, it’s going to go back and now there should be three NSTimers running independently of each other, and it’s going to get worse and worse. If we remember to call invalidate whenever we want to pause or stop the timer so then when we do reset the reference to the NSTimer we have two a brand new instance. That old timer will get garbage collected.  It will stop running. You don’t have to worry about it any more. Which is great. Thanks for watching!

Additional Info

Register to get access to additional resources and info.