views:

92

answers:

3

I tracked down a memory leak with instruments. I always end up with the information that the responsible library is Foundation. When I track that down in my code, I end up here, but there's nothing wrong with my memory management:

- (void)setupTimer {
    // stop timer if still there
    [self stopAnimationTimer];

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(step:) userInfo:nil repeats:YES];

    self.animationTimer = timer; // retain property, -release in -dealloc method
}

the property animationTimer is retaining the timer. In -dealloc I -release it.

Now that looks like a framework bug? I checked with iPhone OS 3.0 and 3.1, both have that problem every time I use NSTimer like this. Any idea what else could be the problem?

(my memory leak scan interval was 0.1 seconds. but same thing with 5 seconds)

+1  A: 

Unless your stopAnimationTimer method is invalidate'ing and release'ing (and then setting to nil) your animationTimer property, you're leaking memory.

Shaggy Frog
You mean `release`'ing instead of `dealloc`'ing, don't you?
bddckr
...Oops! Yes! :)
Shaggy Frog
+3  A: 

Do not call -[NSTimer dealloc]. Ever.

In this case, -scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: is balanced by -invalidate. You do not need to call -dealloc or -release on the timer object.

Jonathan Grynspan
+1 Should be right, if `invalidate` does `release` the timer afterwards. Because he uses `self.animationTimer = timer;` this will first release the old and then retain the new value and therefore this should be leak-safe.
bddckr
A: 

I found it: I had a strong reference to my timer. The run loop retains it. So RC was 2. But because the Timer also holds a strong reference to the target (which in my case retained the timer), I had a deadlock situation. -dealloc was never ever called, and therefore my timer was never ever freed. WTF.

dontWatchMyProfile