简体   繁体   中英

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.

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.

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).

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

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM