Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Mac Player

macrumors regular
Original poster
Jan 19, 2006
225
0
So here is the code

Code:
int main (int argc, const char * argv[]) {

	NSNumber* newNumber;
	int i;
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	for (i = 0; i < 40; i++) {
		newNumber = [[NSNumber alloc] initWithInt:(i * 3)];
		NSLog(@"%d\n", [newNumber retainCount]);
	}
    [pool drain];
    return 0;
}

and here is the result:

Code:
2008-05-18 00:51:11.287 Lottery[845:10b] 2
2008-05-18 00:51:11.289 Lottery[845:10b] 2
2008-05-18 00:51:11.290 Lottery[845:10b] 2
2008-05-18 00:51:11.290 Lottery[845:10b] 2
2008-05-18 00:51:11.291 Lottery[845:10b] 2
2008-05-18 00:51:11.291 Lottery[845:10b] 1
2008-05-18 00:51:11.291 Lottery[845:10b] 1
2008-05-18 00:51:11.292 Lottery[845:10b] 1
2008-05-18 00:51:11.292 Lottery[845:10b] 1
...

Why do the first 4 objects have a retain count of 2?

TIA

Edit: I just found out that some NSNumbers are cached.
 

HiRez

macrumors 603
Jan 6, 2004
6,265
2,630
Western US
Edit: I just found out that some NSNumbers are cached.
Yes, I noticed that before and I think that's correct. The number is retained once for yourself, and then I think the runtime slaps another retain on it for its own cacheing purposes. As you can see it only does this for small numbers (looks like between 12 and 14). Drove me nuts when I was trying to figure out what was going on, it would be nice for Apple to document this (I haven't seen it yet).
 

kpua

macrumors 6502
Jul 25, 2006
294
0
They won't document it because it's an implementation detail. The minute something like this is documented, they're bound to it forever.
 

HiRez

macrumors 603
Jan 6, 2004
6,265
2,630
Western US
They won't document it because it's an implementation detail. The minute something like this is documented, they're bound to it forever.
That's true, but they don't have to be specific. I mean something more generic, along the lines of "* Retain counts for built-in objects may be different than expected due to internal optimization or other implementation details". They could put this note right into NSObject's -retainCount documentation. Just to let the developer know that something really screwy is not going on, because I wasted a lot of time trying to track down the source of that and it seems I'm not the only one. The fact that it only happens in the first dozen or so integers makes it particularly nasty when you first run across it while debugging because the behavior changes even among the same object type.
 

Nutter

macrumors 6502
Mar 31, 2005
432
0
London, England
The solution is to never, ever use the -retainCount method. For anything. Seriously, I don't know why it's even a public method. The retain count of an object is in itself an implementation detail, and is not to be relied upon, even for debugging purposes.
 

Krevnik

macrumors 601
Sep 8, 2003
4,101
1,312
That's true, but they don't have to be specific. I mean something more generic, along the lines of "* Retain counts for built-in objects may be different than expected due to internal optimization or other implementation details". They could put this note right into NSObject's -retainCount documentation. Just to let the developer know that something really screwy is not going on, because I wasted a lot of time trying to track down the source of that and it seems I'm not the only one. The fact that it only happens in the first dozen or so integers makes it particularly nasty when you first run across it while debugging because the behavior changes even among the same object type.

The behavior changes partially because it isn't the same object type in the back-end. NSNumber is backed by a different type depending on what sort of value it was initialized with. Boolean values are considered 'permanently cached' for example, and are of the NSCFBoolean type rather than the NSCFNumber type. Their retain counts are always high, and retain/release are no-ops on an NSCFBoolean.

As the other poster has said, retainCount is pretty much worthless (especially if you are trying to find memory leaks). A better tool would be to actually run Instruments against your application and watch the object allocations.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.