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 namespaceUR开发者_开发知识库I:(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.
精彩评论