Re: Is Apple's singleton sample code correct?
Re: Is Apple's singleton sample code correct?
- Subject: Re: Is Apple's singleton sample code correct?
- From: David Gimeno Gost <email@hidden>
- Date: Sat, 26 Nov 2005 16:53:05 +0100
On 26 Nov 2005, at 09:14, Shawn Erickson wrote:
Consider reviewing what I use...
<http://www.cocoadev.com/index.pl?FTSWAbstractSingleton>
I don't get it, sorry.
I was answering in the point of view of an implementation like the one
Apple outlines in the documentation you noted. The one I use moves
init out to an initSingleton method that is private and not advertised
in headers (note the version of the website was simplified, normally I
have initSingleton in a private category in the .m file).
I still don't get it.
Yes, you avoid the problem of repeatedly calling -init by not allowing
it, but then you don't allow instances of the singleton to be obtained
by means of [[alloc] init] either and thus your singletons cannot be
created as any other object, which I thought was the whole point of
overriding +allocWithZone:.
1. If I wanted to allow getting the singleton instance variable
through [[alloc] init] calls, then I would write +allocWithZone: as
follows:
+ (id) allocWithZone: (NSZone*) zone
{
@synchronized( self ) {
if ( sharedInstance == nil ) {
sharedInstance = [super allocWithZone: zone];
} else {
[sharedInstance retain];
}
}
return sharedInstance;
}
This is sufficient to ensure that memory for only one object is
allocated [1] on the first attempt and for all other attempts an
synthetic "allocation" takes place by adding a retain. What it doesn't
prevent against is the possibility of the singleton being deallocated
since code that does [[mySingleton alloc] init] will send the
"allocated" instance a release or autorelease message since they are
expected to follow the memory contract.
[1] At least when using normal messaging to the class to allocate an
instance.
But I don't want to prevent the singleton from being deallocated. I
think it's wrong to add that as a requirement to the singleton in the
general case. Anyway, the code above indeed has the problem that
allocating and then releasing the singleton without going through the
+sharedInstance method first leaves a dangling shared instance
variable, as Uli Kusterer has correctly pointed out.
2. The -retain and -release methods shouldn't be overridden. There is
no point in doing so and the way it is done in the current sample
code guarantees that code breaking Cocoa's memory management rules
will go by unnoticed.
Correct they don't need to be overridden assuming you do something
like you did in your code above. I would however likely throw an
exception if somehow dealloc got called. This would be an active way
of detecting an over release scenario, at least possibly a little
closer to the source. An over retain or under release case will not be
detected since no memory leak would exist as a result, you would have
to watch retain counts and understand code to do that.
Yes, of course, I have nothing against overriding those methods for
debugging purposes to ensure that client code is written correctly.
Regards.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden