Mike D
Mike D

Reputation: 4946

Creating a new NSString instance has retain count of 3

I am trying to copy a string that is passed into a method like so:

-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    NSLog( @"elementName, %@:  %i", elementName, [elementName retainCount] ); // rc = 2

    if ( currenttag )
        [currenttag release];

    NSLog( @"currenttag:  %i", [currenttag retainCount] ); // rc = 0

    //currenttag = [[NSString alloc] initWithString:elementName];   // track current element
    [self setCurrenttag:elementName];

    NSLog( @"currenttag:  %i", [currenttag retainCount] ); // rc = 3

    .
    .
    .
    }

setCurrenttag is a synthesized accessor ( @property (copy) ). My understanding was this would create an entirely new object instead just a reference to elementName. The above behaves as though it is keeping a reference to elementName and calling retain. The commented out bit of code shows the same behaviour.

These methods are implementing the NSXMLParserDelegate protocol, but I do need keep a track of certain element names (but not all).

Is there something I am missing concerning NSString objects and memory management on the iphone.

Also, as reference, I am running this on the iPhone simulator with XCode 3.6.

Upvotes: 2

Views: 282

Answers (6)

Tom Harrington
Tom Harrington

Reputation: 70976

For immutable Foundation classes like NSString, copy simply retains the object. Duplicating an object that's known to be immutable would be a waste of resources, so it doesn't happen. This is hinted at in the documentation for the NSCopying protocol. One of the options for implementing the protocol is:

  • Implement NSCopying by retaining the original instead of creating a new copy when the class and its contents are immutable

In general, if you know that instances of one of your classes will be immutable, it's entirely valid to retain the target object rather than duplicate it.

Upvotes: 5

Oscar Gomez
Oscar Gomez

Reputation: 18488

In my experience the retainCount does not always return the actual retain count, and it can be tricky. NSString is an immutable object, so it might behave differently than other objects, I am not sure if Objective C implements a String pool like java does, since it doesn't mention so in the documentation.

Upvotes: 0

dasdom
dasdom

Reputation: 14073

Don't trust the retainCount. Just release every object for which you called alloc, copy, retain and new.

Upvotes: 0

Daniel Dickison
Daniel Dickison

Reputation: 21882

Don't count on retainCount to be intuitive. What's likely happening here is that the string in question is not mutable, so a "copy" ends up just retaining the existing string (which is fine since it can never change).

Upvotes: 2

highlycaffeinated
highlycaffeinated

Reputation: 19867

Just a guess, but since NSString is immutable, it might be an optimization that the property does a retain instead of creating a new object.

Upvotes: 0

shreyasva
shreyasva

Reputation: 13546

Whenever you deal with objects you must never deal directly with the retain counts, you must deal with them only in terms of differences. All you must know is retain is +1 and release is -1

Upvotes: 1

Related Questions