NSString retain Count
Asked Answered
A

3

7

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.

Auld answered 7/9, 2009 at 17:36 Comment(7)
Duplicate of #403612 And there's a good answer there too.Super
Why is this a community wiki?Smokechaser
Well sorry if i click somewhere where i should not, new to this website so really don't know what it mean, sorry.Auld
Don't worry. It's fine to make it a community wiki.Fluky
However, it's not OK for you to ignore advice from experienced Cocoa programmers and just be like, "Whatever! I'm going to use NSMutableStrings instead of learning to use Cocoa properly!"Fluky
Well i am not ignoring their advice or something, but right now i am unable to grasp the concept, for just not to stay in confusion, its best for me to use NSMutableString, because i hate confusion loz.Auld
What's confusing about it? If you follow the memory management rules, you'll never go wrong: developer.apple.com/mac/library/documentation/Cocoa/Conceptual/… Direct quote: "Typically there should be no reason to explicitly ask an object what its retain count is (see retainCount). The result is often misleading, as you may be unaware of what framework objects have retained an object in which you are interested. In debugging memory management issues, you should be concerned only with ensuring that your code adheres to the ownership rules."Smokechaser
S
27

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.

Smokechaser answered 7/9, 2009 at 17:36 Comment(13)
OK can you tell me the way through which i will get the retain count of 1, in case of NSString?Auld
@Auld 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.Smokechaser
@ Dave DeLong That is how i have been thinking, if have created an object with NSString *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!Auld
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.Auld
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.Gilud
@Auld 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.Smokechaser
@Gilud - I know (see my first comment). I put it in there to explain why the retainCount he was getting was so high.Smokechaser
@Dave From 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?Auld
@Dave So in case of NSString, i should be releasing it?Auld
@Auld it's possible. it really depends on the compiler. But YES you should release it. You called +alloc, which means you should call -release.Smokechaser
@Dave Thats 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.Auld
@Auld 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...Smokechaser
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]; }Gospel
B
4
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.

Bamboo answered 7/9, 2009 at 17:36 Comment(0)
P
2

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.

Prolong answered 7/9, 2009 at 17:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.