tags:

views:

403

answers:

5

Hi,

Just couple of days i was working on a project and i have to see what is retain count of a string.

But it always return me "2147483647", Why it is so?

Check out this code to check it yourself.

NSString *str = [[NSString alloc] initWithString:@"Hello World"];
NSLog(@"String Retain Count: %i", [str retainCount]);

So my question is why it is not returning 1 like other objects return, why i am getting "2147483647"

Thanks in advance.

+2  A: 

Duplicate of http://stackoverflow.com/questions/403112/objective-c-nsstring-property-retain-count-oddity

And there's a good answer there too.

marcc
I think this is a rite of passage for all Cocoa developers. At least that's what I'm calling it now!
Shaggy Frog
Well i see that question before but it is not not answering the question and puzzle is still there why it is happening?
itsaboutcode
+2  A: 

The string is being optimized at compile-time to a statically allocated instance of NSString in order to save on some variable overhead and the like. You're seeing such a high retain count because static strings have a retain count of the maximum integer on whatever platform you're developing on.

Tim
+6  A: 

The compiler is smarter than you.

It sees @"Hello world" and thinks "Aha! A constant string!"

It then sees [[NSString alloc] initWithString:@"Hello world!"] and thinks "Aha! An immutable object created with a constant string!"

It then collapses both of them down into a single NSConstantString, which has a retainCount of UINT_MAX, so that it can never be released.

Dave DeLong
OK can you tell me the way through which i will get the retain count of 1, in case of NSString?
itsaboutcode
@itsaboutcode I would recommend not thinking about this in terms of retainCounts, but instead think about "I allocated this string, so I must release it", and let the retainCounts sort themselves out. In the few years I've been writing in Objective-C, I can't think of a single instance when I've needed to bother with the retainCount. If you follow the memory management rules, you'll be fine.
Dave DeLong
@ Dave DeLongThat is how i have been thinking, if have created an object withNSString *str = [[NSString alloc] initWithString:@"Hello World"];Then i should release it, right? But if i have to release it i should know what is its retain count? Otherwise i will be sending messages to object which is not there and result will be that my program will crash!
itsaboutcode
But i have found a strange behavior here. When i do the same thing with NSMutableString, it return me a retian count of 1.NSMutableString *str = [[NSMutableString alloc] initWithString:@"Hello World"];NSLog(@"String Retain Count: %i", [str retainCount]);Check this out.
itsaboutcode
Dave, you don't need to worry about what the retain count *is*, just that you have the correct number of init/releases in your code. If you init something, you release it, and that's all good. The specialisation of UINT_MAX in this case means that even if you do release it, it will still be UINT_MAX afterwards.
AlBlue
@itsaboutcode if you alloc it, you release it. End of story. If your code crashes on the release because you've over-released the object, then you've done wrong. The reason that the NSMutableString returns a retainCount of 1 is *precisely* because it is mutable. It can be changed, which means the compiler cannot optimize it into a constant string.
Dave DeLong
@AlBlue - I know (see my first comment). I put it in there to explain why the retainCount he was getting was so high.
Dave DeLong
@DaveFrom your answer it seems to me that every immutable object will get a retain count of "UINT_MAX", but i dont think so its the case?
itsaboutcode
@Dave So in case of NSString, i should be releasing it?
itsaboutcode
@itsaboutcode it's possible. it really depends on the compiler. But YES you should release it. You called +alloc, which means you should call -release.
Dave DeLong
@DaveThats the problem, though i am releasing it but every time i release it it's retain count remain "2147483647", so i have decided not to use NSString ever again and i will only use NSMutableString instead so that i have no problem in debugging my app. Thanks everyone.
itsaboutcode
@itsaboutcode IGNORE RETAINCOUNTS. NSString is there for a reason: use it when you don't need a mutable string. If you alloc an object, release it. It's really not that difficult...
Dave DeLong
Retain counts are for the computer, not for you. You should only be concerned with what you own, and relinquishing your ownership when you are done. The coalescing into a single constant string is memory savings for you. if (!horse.isAlive) { [self beat:horse]; }
Wevah
A: 
NSString *str = [[NSString alloc] initXXX

usually would allocate some RAM and return you a pointer. This RAM would then be subject to releases and reatins. However, when you do:

NSString *str = [[NSString alloc] initWithString:@"Hello World"];

the string returned is @"Hello World", which is already allocated because it was a string literal. Since it is a string literal, there is no way to release it, and thus the system has to mark it as unreleasable. The way it does that is to set its retain count to the max integer value.

NString  *str = [[NSString alloc] initWithFormat:@"Hello World. Today is @%", todayDate];

This string will have a retainCount of 1. Although there is a string constant in there, it is appended to by another string. Since you can't modify that constant string, a copy of the "Hello World. " string is made, and the content of the todayDate string is added to that. That memory now is given ownership to the caller, with a retainCount of 1.

mahboudz
A: 

But how to explain this code:

char *cchar = "A1";
NSString *strss=[[NSString alloc]initWithUTF8String:cchar];
NSLog(@"%d", [strss retainCount]);

the result is 1, but when try this:

char *cchar = "A";
NSString *strss=[[NSString alloc]initWithUTF8String:cchar];
NSLog(@"%d", [strss retainCount]);

the result is UINT_MAX!

Z.Y. Zhou