Sahitya Tarumani
Sahitya Tarumani

Reputation: 429

Managing memory with NSString objects

Here is what i have in my main method:

int main (int argc, const char * argv[]) {  
    NSString *string=[[NSString alloc]init];  
    NSLog(@"%@   The retain count is:%d", string, [string retainCount]);  
    NSLog(@"Hello, World!");  
    return 0;  
}    

The output on executing this piece of code is "The retain count is :-1".
I was expecting it to give me 1 as the retain count, since i created the object using alloc. I have similar problems when i try to retain or release the NSString objects.

When i try with NSArray, i get the retain count immediately after creation of object as 2. I do not understand the mechanism of how the objects are being treated. Please explain! Thanks in advance..

Upvotes: 0

Views: 453

Answers (2)

DarkDust
DarkDust

Reputation: 92316

You shouldn't focus on the raw retain count value, as this can be a different value depending on various things. For example, in your first line you are allocating what is the equivalent of @"", that is an empty string. This is optimized by an object that cannot be deallocated and is shared wherever you're "allocating" it. The same is true for all static strings, e.g. look the value returned by [@"Hello" retainCount].

Instead you should focus on relative retain count. That is, is the retain count increased (+1), does it stay the same (+0) or is it decreased (-1). You always need to make sure that these relative value sum up to 0.

An example:

Foo *foo = [[Foo alloc] init];
[foo retain];
[foo release];
[foo autorelease];

The alloc method returns an object with +1, and retain also increses the count by 1. So by the end of line 2, we're at +2. Both release and autorelease have the effect of -1, so at the end of line 4 you're at +0 and everything is fine.

There are a few simple rules: if the method name is alloc, starts with the words copy or create then you will get an object with retain count +1. All other methods (especially those start with get) should return objects with retain count +0. If your method needs to create an object but its name implies that a +0 object should be returned, you can do this:

- (Foo *) bar {
    Foo *result = [[Foo alloc] init]; // +1
    return [result autorelease]; // -1
    // Object lives until the autorelease pool is drained,
    // but relative retain count is +0.
}

Upvotes: 14

Jens Ayton
Jens Ayton

Reputation: 14558

-1 is what you get if you cast UINT_MAX to a signed value. UINT_MAX is the documented retain count of objects which are never released, which includes string literal objects.

Speaking of the documentation, I suggest reading the big box about how retainCount is generally not useful.

Upvotes: 8

Related Questions