views:

90

answers:

3

If a retain (reference) count of an object is greater than 1 in a dealloc method right before releasing does this mean there will be a memory leak?

I was debugging my code to find another issue but then ran into this subtle one. One of my object's retain counts was 3 in the dealloc method. This object is a property with retain and is only called within the class. Now I imagine that the retain count should be 1 for all objects in the dealloc method before releasing right?

Here's a sample dealloc method in a custom class:

- (void)dealloc {
    // Prints: "myObject retaincount: 3"
    NSLog(@"myObject retaincount: %d", [myObject retainCount]);

    // myObject retain count will be 2 after this call
    [myObject release];

    [super dealloc];
}

Is this normal?

+2  A: 

If myObject is passed to some other object (say 'anObj') via a method (say 'method:') as in

 [anObj method:myObject];

anObj can retain myObject if needed. Then it is perfectly reasonable that when dealloc of the object containing myObject is called, the retain count of myObject is more than 1.

Your code is still OK: the responsibility of the containing object is to release ownership when it's done with it. After [myObject release], myObject won't be dealloc'ed. Instead, it will be dealloc'ed when anObj releases it.

Yuji
Ah yes, makes sense. I guess I was confused because I never explicitly assign anything to myObject but I did associate it with a UI component in IB. So maybe IB somehow retained this object 3 times.
Nebs
+5  A: 

From Apple regarding -retainCount:

Important: This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.

Preston
Everyone should be forced to read this when they get a stackoverflow account.
kubi
A: 

What you want to do instead of printing out the retain count, is to run the ObjectAlloc Instrument against your code, with reference counting turned on (click on the (i) of the instrument and re-start the instrument recording your app).

Then you can go to a specific instance of an object, and get the full retain/release history for it - that can help figure out if something is retaining the object that should not be.

Another quick check would be to set a breakpoint or put a log in dealloc of whatever class myObject is, so that you can see directly if the object is getting deallocated when you expect it to - it could be that it's still got a larger retain count there, but once the autorelease pool is emptied it will go away.

Kendall Helmstetter Gelner