0
votes

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?

3
It is almost never a good idea to speculate about what retain counts should be. Or to draw conclusions from what they are. Or, actually, to look at them at all...walkytalky
NEVER LOOK AT THE RETAINCOUNT. IT DOES NOT EXIST.Dave DeLong
retainCount does not return 'current' retaining count you imagine. See reference documentation. You must read at least memory management chapter when you start to learn new language.eonil
@Eonil: This is why you down-voted the question? Yes it does return the 'current' retain count, but that retain count is not always predictable as it may have been retained elsewhere as well. I have read the memory management chapter, have you?nebs

3 Answers

6
votes

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.

2
votes

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.

0
votes

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.