retain count weirdness

Member
Posts: 208
Joined: 2005.04
Post: #1
Will someone please explain to me how the following is possible?

Code:
aNumber = [[NSNumber alloc] initWithLong:0];
        
NSLog(@"%d", [aNumber retainCount]);

prints out 1943!!!!!! WTF??? It SHOULD print out 1, should it not?

- aNumber is an instance variable in a subclass of NSObject

- the above code is my -init method

- I go multithreaded in the +initialize method (but, of course, I don't touch any instance variables in the +initilize method)

- I'm running Tiger


If anyone could shed some light on this mystery, I'd be eternally grateful. I've been trying to fix some retain/release issues in one of my apps for 2 days straight (without much luck). The above problem is just one of many unexplained phenomena I've been experiencing. Maybe there are ghosts in Tiger?

Andrew
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #2
I figured I'd write a simple program to see if the problem persists without multithreading. Indeed, it does. The following code prints out 17:

Code:
#import <Cocoa/Cocoa.h>

@interface AppController : NSObject
{
    NSNumber *aNumber;
}
@end

@implementation AppController
- (id)init
{
    if (self = [super init])
    {
        aNumber = [[NSNumber alloc] initWithLong:0];
        NSLog(@"%d", [aNumber retainCount]);
    }
    return self;
}
@end
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #3
My Cocoa is incredibly rusty, but I can at least confirm that this happens to me as well when I run your code. You do get complaints that there is no NSAutoReleasePool in place, but I think that is just NSLog complaining.
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #4
Fenris Wrote:You do get complaints that there is no NSAutoReleasePool in place

According to Apple,
Quote:NSAutoreleasePools are automatically created and destroyed in the main thread of applications based on the Application Kit, so your code normally does not have to deal with them there.

So I don't think that's the problem. Thanks for trying to help though Smile

I'm starting to think that this is a bug in the Foundation framework. Try using numbers other than zero:
When I use 1, I get a retain count of 19.
When I use 2, I get a retain count of 5.
When I use some arbitrary number like 73, I get a retain count of 1 (which is correct).
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2006.10
Post: #5
Tiger now caches often-used NSNumbers which currently includes -1 through 12.
The details are here:

http://developer.apple.com/releasenotes/...ation.html
Quote this message in a reply
Moderator
Posts: 771
Joined: 2003.04
Post: #6
belthaczar Wrote:Tiger now caches often-used NSNumbers which currently includes -1 through 12.
The details are here:

http://developer.apple.com/releasenotes/...ation.html

Apple Wrote:In Tiger "popular" numbers include -1..12, although this might very well change at any point, including in a software update.


LOL LOL - I wonder how they determined that... Blink
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #7
belthaczar Wrote:Tiger now caches often-used NSNumbers which currently includes -1 through 12.
The details are here:

http://developer.apple.com/releasenotes/...ation.html


Thank you sooo much for the reply! Grin

What's next? Are they going to start caching "popular" NSStrings like @"Mac OS X"?
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #8
*chuckles*

Caching numbers? You are kidding right? Is there really that much overhead involved with Obj-C that numbers are classes bulky enough to merit caching?!

o_O_o
Quote this message in a reply
Member
Posts: 72
Joined: 2004.06
Post: #9
A simple foundation project with no appkit confirms this. retain count for initWithLong:1 is 2 which is what you'd expect from the cached one.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #10
Puzzler, malloc is slow. Every call avoided is a potentially significant speedup. Particularly with more and more cocoa apps using key-value coding, and therefore using many more NSNumbers than they used to, this is probably a very smart move indeed.
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #11
But I mean seriously. Why is it allocating it with malloc? Why isn't it stack allocated if it's temporary? I dunno, seems really stupid to have a wrapper class for numbers to me anyway... Whatever though, I guess this is just where OOP leads...
Quote this message in a reply
Member
Posts: 208
Joined: 2005.04
Post: #12
Puzzler183 Wrote:I dunno, seems really stupid to have a wrapper class for numbers to me anyway

Container classes, like NSArray, NSSet, NSDictionary, etc. can only hold NSObjects (or subclasses of NSObject). Thus, if you want to store some numbers in one of these container objects, you need to have a number class which is a subclass of NSObject. That's why they created wrapper classes like NSNumber.

Much of Cocoa's way of doing things comes from the fact that everything in the framework descends from a root class: NSObject.
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #13
Also, it should be pointed out that you normally use the primitive data types, not NSNumber. So for instance, you don't do vector calculus with NSNumber. NSNumber is a wrapper for a number that needs a little more punch (and that needs to be descendant from NSObject). Java does the same thing with all its Integer, Double and the like.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  AVAudioPlayer: AddRunningClient starting device on non-zero client count sefiroths 2 6,002 Dec 20, 2010 04:17 AM
Last Post: sefiroths
  NSArray Weirdness MikeC 4 3,859 Jan 5, 2008 06:41 PM
Last Post: MikeC
  yet another retain/release question... Andrew 3 2,829 May 30, 2005 03:21 PM
Last Post: Andrew
  C String weirdness Muffinking 2 4,034 Jun 10, 2002 04:09 PM
Last Post: OneSadCookie