Reputation: 768
I have a question that may not be of any practical use right now since ARC is highly encourage, but I'm studying memory management and there's something I didn't quite understand.
I have this method
+(NSNumber *)releaseTooEarly
{
NSNumber *createdNumber = [[NSNumber alloc] initWithInteger:5];
NSLog(@"retain count before release: %d", createdNumber.retainCount); //Prints 2
[createdNumber release];
NSLog(@"%@", createdNumber); //Prints 5
return createdNumber;
}
I'm wondering if I'm inside an autorelease pool that is not allowing me to deallocate the object within the function.
I know I should be using ARC but I just want to understand the reason of this results.
Upvotes: 1
Views: 128
Reputation: 539685
You should never rely on a particular value of the retain count (see http://whentouseretaincount.com).
In this particular case (as can be seen in http://www.opensource.apple.com/source/CF/CF-476.19/CFNumber.c), NSNumber
caches the created objects for integer values between
(-1) and 12, so that calling
[[NSNumber alloc] initWithInteger:5];
repeatedly will always return the same instance. The cache holds one additional reference to the object
which is the reason for retainCount == 2
, and also explains why the object is not
actually destroyed if you release it.
But this are only implementation details!!. As said above, you should not use the retain count. And even if an object is deallocated that not necessary mean that the memory of the object is invalidated, so accessing the object might show a result.
See "Basic Memory Management Rules" in the "Advanced Memory Management Programming Guide" about the rules:
release
or autorelease
objects that you own.retain
.The correct version of your method would be
+ (NSNumber *)releaseCorrectly
{
NSNumber *createdNumber = [[[NSNumber alloc] initWithInteger:5] autorelease];
return createdNumber;
}
The autorelease
balances the alloc
, but ensures that the object is still valid
when returning to the calling method. It will be released when the current autorelease
pool is destroyed, e.g. when program control returns to the main event loop.
Upvotes: 2