Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,563
6,062
I have an object that, in its init method, sets up an ivar with an NSTimer. The object itself is the target for the timer, which causes the object to get a +1 to its retain count.

It seems to me that to balance setting up the timer, I need to tell the timer to invalidate and release. Since it was created in init, the balance belongs in dealloc, correct?

But this causes an issue:
- The object has been +1'd by the timer.
- Thus the object won't get its corresponding -1 until the timer is invalidated.
- The timer won't be invalidated until the object's retainCount hits zero.
- The retainCount won't hit zero until the timer is invalidated.

So it seems like there are two possibilities, neither of which is any good:
1 - I could call autorelease on the object right after the timer is created. But then it would be over released when the timer is told to invalidate in the dealloc method, would it not?
2 - I can ignore the issue and the program will appear to work, except there will be a memory leak.

Edit: I attempted to do #1. I get this message when the object is dealloced.
Code:
*** -[CFRunLoopTimer release]: message sent to deallocated instance 0x105d0cd70

I tried adding in a [self retain] to the dealloc method, but that didn't change anything (not that I really expected it to. Even if it worked, I wouldn't have considered it an acceptable solution.)

Edit 2X: Actually... I might be misreading the issue... it seems that the issue is that when I set up the timer, I didn't retain it. Instead, it's just a scheduled timer which adds it to the run loop, which retains it. When I call invalidate, that causes it to remove it from the run loop, which releases it. So releasing the timer after invalidating it is causing the over-release issue.
 
Last edited:

mfram

Contributor
Jan 23, 2010
1,309
344
San Diego, CA USA
Whether you need release or not depends on which method you are calling to schedule the timer. Read the Timer Programming Topics guide. It will give you examples of how to keep track of timers in your class. There's even a section called "Memory Management" that will help guide you. But really what it comes down to is if you use the 'scheduleTimer...' methods, then you can call 'invalidate' later, set your iVar to nil, and you don't have to worry about releasing the timer.
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
First rule of timers: when you invalidate a timer you set its ivar to nil. Anything different leads to madness.

Typically there is some event that indicates that the timer should be invalidated. Things like: user hits back button, network request returns, user hits pause or stop button, etc. Use those events to invalidate your timer. Then the view controller won't be retained anymore and the retain-cycle is broken.
 

Ides

macrumors member
Mar 27, 2012
95
0
Timer

If you set up the timer to not repeat itself, then as soon as it fires it will be invalidated and removed from the run loop, and will release your object on its own. You don't need to call release or invalidate on it.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.