6

After trying to print retainCount of object I get 2147483647. Why do I get such a result? It should be 1, shouldn't?

NSString *myStr = [NSString new];
NSUInteger retCount = [myStr retainCount];
NSLog(@"refCount = %u", retCount);

2011-09-08 17:59:18.759 Test[51972:207] refCount = 2147483647

I use XCode Version 4.1. Tried compilers GCC 4.2 and LLVM GCC 4.2 - the same result. Garbage Collection option was set to unsupported.

JastinBall
  • 873
  • 8
  • 25

4 Answers4

15

NSString is somewhat special when it comes to memory management. String literals (something like @"foo") are effectively singletons, every string with the same content is the same object because it can't be modified anyway. As [NSString new] always creates an empty string that cannot be modified, you'll always get the same instance which cannot be released (thus the high retainCount).

Try this snippet:

NSString *string1 = [NSString new];
NSString *string2 = [NSString new];
NSLog(@"Memory address of string1: %p", string1);
NSLog(@"Memory address of string2: %p", string2);

You'll see that both strings have the same memory address and are therefore the same object.

omz
  • 53,243
  • 5
  • 129
  • 141
  • 4
    in addition: this is probably reasoned in the flyweight design pattern and this: "For objects that never get released (that is, their release method does nothing), this method should return UINT_MAX" (Quote from NSObject-Class-Reference) – thomas Sep 08 '11 at 15:24
12

This doesn't directly answer your question, but retainCount is not really all that useful and should not be used for testing. See this SO post for details. When to use -retainCount?

Community
  • 1
  • 1
Silvae
  • 594
  • 1
  • 8
  • 20
  • 3
    +1, there is no reason *ever* to look at `retainCount`, other than curiosity. If you evaluate `retainCount` you're doing something very wrong. – DarkDust Sep 08 '11 at 15:17
  • 5
    The only effect of checking your object's retain count is that you end up back here posting bewildered questions about why that number is moving around without you. The answer is: that number moves around without you. So don't use it for debugging your retain/release code. – Dan Ray Sep 08 '11 at 15:18
4

While NSString's are an odd case (there are others in the framework) you might also run across this in other clases - it's one of the ways of creating a singleton object.

A singleton only exists once in the app and it's pretty important that it never gets released! Therefore, it will overwrite some methods of NSObject including (but not limited to):

- (id)release {
    // Ignore the release!
    return self;
}

- (NSUInteger)retainCount {
    // We are never going to be released
    return UINT_MAX;
}

This object can never be released and tells the framework that it's a singleton by having a ludicrously high retain count.

Checkout this link for more information about singleton objects.

deanWombourne
  • 38,189
  • 13
  • 98
  • 110
  • 2
    It tells the framework no such thing; `retainCount`'s return value is never used by the frameworks (outside of a couple of special cases that are limited to a very particular scope of use). That a recommendation to override `retainCount` in the context of singleton's exists is, in and of itself, a waste of time. – bbum Sep 08 '11 at 17:54
  • Sorry, I didn't mean it in such an explicit way - it's just a very badly worded sentence! I meant something like in http://www.cocoadev.com/index.pl?SingletonDesignPattern - i.e. 'denotes a object that cannot be released' :) – deanWombourne Sep 09 '11 at 16:56
1

I've seen this a couple of times regarding NSStrings, the retainCount returns the maximum count instead of the actual one when you try to look at retainCounts of strings in this manner.

Try this;

NSString *myStr = [[NSString alloc] init];
NSUInteger retCount = [myStr retainCount];
NSLog(@"refCount = %u", retCount);

Edit: Restored NSUInteger

Madhu
  • 2,429
  • 16
  • 31
  • 1
    `retainCount` returns NSUInteger. Useless though the method is, you should at least use the right return type. Unsigned and signed integers are not transparently interchangeable. – bbum Sep 08 '11 at 17:52