Why has NSNumber such strange retainCounts?

NSNumber* n = [[NSNumber alloc] initWithInt:100];
NSNumber* n1 = n;

In the code above, why is the value of n's retainCount set to 2? In the second line of the code, I didn't use retain to increase the number of retainCount.


I found a strange situation. Actually the retainCount depends on the initial number:

NSNumber *n = [[NSNumber alloc] initWithInt:100]; 
// n has a retainCount of 1

NSNumber *n2 = [[NSNumber alloc] initWithInt:11]; 
// n has a retainCount of 2

Stop. Just stop. Never look at the retainCount of an object. Ever. It should never have been API and available. You're asking for pain.

There's too much going on for retainCount to be meaningful.


Based on this link here, it's possible that there's some optimization going on under the covers for common NSNumbers (which may not happen in all implementations hence a possible reason why @dizy's retainCount is 1).

Basically, because NSNumbers are non-mutable, the underlying code is free to give you a second copy of the same number which would explain why the retain count is two.

What is the address of n and n1? I suspect they're the same.

NSNumber* n = [[NSNumber alloc] initWithInt:100];

NSLog(@"Count of   n : %i",[n retainCount]);

NSNumber* n1 = n;

NSLog(@"Count of   n : %i",[n retainCount]);
NSLog(@"Count of   n1: %i",[n1 retainCount]);
NSLog(@"Address of n : %p", n);
NSLog(@"Address of n1: %p", n1);

Based on your update, that link I gave you is almost certainly the issue. Someone ran a test and found out that the NSNumbers from 0 to 12 will give you duplicates of those already created (they may in fact be created by the framework even before a user requests them). Others above 12 seemed to give a retain count of 1. Quoting:

From the little bit of examination I've been able to do, it looks as if you will get "shared" versions of integer NSNumbers for values in the range [0-12]. Anything larger than 12 gets you a unique instance even if the values are equal. Why twelve? No clue. I don't even know if that's a hard number or circumstantial.

Try it with 11, 12 and 13 - I think you'll find 13 is the first to give you a non-shared NSNumber.