views:

184

answers:

3

Im using alot of timers in my application. For recording time, moving object, fading etc. I use the same timer for several puposes in the same view at different times. How should I declare and invalidate or release my timers properly?

Atm Im declaring the timers like this:

fadeTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(bortInfo) userInfo:nil repeats:YES];

and as soon as im not using it im doing this:

[fadeTimer invalidate]; 
fadeTimer = nil;

The retain count when im leaving the view is 0 on every timer. Should i release the timer in the dealloc aswell? My app runs quite good, but from time to time it crashes.

The clockTimer that i use for updating a label with the time uses

[[NSRunLoop mainRunLoop] addTimer:clockTimer forMode:NSRunLoopCommonModes];

Do i need to do anything with this mainLoop once i invalidate the clockTimer?

All in all please support me with some info about working with timers.

Thank you very much!

Joakim

A: 

Hi,

You're not retaining your timers properly - if you want to refer to them again you should retain them. I'd do this with a property i.e. in your header file

@property (nonatomic, retain) NSTimer *fadeTimer;

and change your code to say

self.fadeTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(bortInfo) userInfo:nil repeats:YES];

// Put this whenever you want to remove your timer and in your dealloc method.
[fadeTimer invalidate];
self.fadeTimer = nil;

This will make sure that your timer is retained by your object. Otherwise you just have to hope that the timer stays around and doesn't get autoreleased by the iPhone. And as you say it's crashing occasionally, this might be the reason ;)

I'm afraid I don't know much about run loop but am confused why your don't just use a normal NSTimer to schedule things - why bother interacting with the run loop at all?

deanWombourne
Not entirely true; a "scheduled" timer is retained by the run loop.
tc.
Very true but I'm don't know how scheduled timers act with long timeouts or in low memory situations etc etc - better safe than sorry!
deanWombourne
A: 

Hi thanks for your answer. the @property im actually doing atm so that is not the problem. But im not using "self." i guess that wont make any difference, but ill try.

"Put this wherever you want to remove your timer and in your dealloc method."

So im using my timer then it should be paused then i user invalidate and nil. then i use it again with self.fadetimer = ... then i invalidate and = nil for the last time. But i shouldnt have it in dealloc if im sure that the timer is always invalidated and put to nil before deallocing i guess. Then it will be invalidated twice.

The runloop I need because otherwise my timer wont run while im scrolling in my UIScrollView. I have a label getting updated every 0.1 sec and it stops if I dont have that.

Joakim Börjesson
Not using `self` means you bypass the property setter and hence don't `retain`. And you can safely `invalidate` and set to `nil` in `dealloc` as a safety net, since it is OK to call methods on `nil`. Also, you should comment or edit your question rather than posting something like this as an answer.
walkytalky
A: 
  • Scheduled timers are retained by the run loop, and retain their target. If you want to retain the timer, you have to jump through a few hoops to prevent a retain cycle (I wrote a non-retaining proxy class, which is a bit messy but it works).
  • Don't manipulate the run loop unless you know what you're doing (I don't). A "scheduled" timer is already added to the main run loop. If you're generating clockTimer like fadeTimer, then it's being added to the run loop twice.
  • "from time to time it crashes" doesn't help anyone. Run it in the debugger and see where it crashes. It might even print some messages to the console if you're lucky.
tc.