Whenever I want to make a timer, I just do:
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(someMethod)
userInfo:nil
repeats:NO];
rather than
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(someMethod)
userInfo:nil
repeats:NO];
Is the first one a memory leak? What’s the correct way to use them?
You have no memory problem in either snippet; you simply have to make a choice about your needs for interacting with the timer.
When you schedule a timer, the run loop retains it, and a reference to the timer is passed along when it fires and its selector — e.g.,
(void) doTimerThing: (NSTimer *)tim1 — is used, so it isn’t strictly necessary for you to put it into a variable and retain it yourself. Apple explains this pretty clearly in the “Memory Management” section of the Timer Programming Topics doc.If, however, you might want to invalidate the timer before it fires (or in between fires for a repeating timer), you do need to have a reference to it. In that case, it is also a good idea to call
retainon it. ThescheduledTimerWithTimeInterval:target:...method returns an object that you do not own, and you should not make assumptions about the memory status of objects you don’t own (including whether they are in an autorelease pool or not, or how long the run loop is going to keep the timer around). If you need the timer (or any object) to stick around, you should make a claim of ownership on it by callingretain.1 Note that a timer’s method should always have one parameter; the selector in your snippet looks like it is for a method that does not. The timer seems to work that way, but you’re operating contrary to the documented interface.