• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Is Apple's singleton sample code correct?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Is Apple's singleton sample code correct?


  • Subject: Re: Is Apple's singleton sample code correct?
  • From: David Gimeno Gost <email@hidden>
  • Date: Fri, 2 Dec 2005 06:47:57 +0100

On 2 Dec 2005, at 02:38, mmalcolm crawford wrote:

Actually I've always had both approaches in mind and I've strived to not make this explicit until now on purpose.

This frankly beggars belief.

Yes, you're right. "Always" here meant since I was told to use notifications instead of -dealloc. I had nothing about this in mind when I started this thread.

This far into the thread and we suddenly find that you haven't even fully described your pattern. The very fact that you appear to have been unable to clearly articulate and prove either your problems with the current pattern or your proposed solution speaks volumes

Well, I thought I had stated clearly that Uli Kusterer had already done it, so I considered it more appropriate to refer to his implementation rather than proposing it as if it was mine, but here it is if that's the problem (minor changes made and comments added, let me know if there is something wrong about making the changes):

@implementation MySingleton

+ (MySingleton*) sharedInstance
{
static MySingleton* sSharedInstance = nil;
@synchronized( self ) {
if ( sSharedInstance == nil ) {
// Note: calls -singletonInit instead of -init
sSharedInstance = [[MySingleton alloc] singletonInit];
}
}
return sSharedInstance;
}

- (id) init
{
// If we got here, the instance was created by alloc/init
// instead of +sharedInstance. Discard it and return the
// one created by +sharedInstance instead.
// Send a retain message to account for the
// call to alloc/init made by the client.
[self release];
self = [MySingleton sharedInstance];
return [self retain];
}

- (id) singletonInit
{
self = [super init];
if ( self != nil ) {
// Your singleton initialization goes here.
// This method will never be called more than once
// for the same object.
}
return self;
}

@end

You have not explained how any of these alleged "nasty side effects" manifest themselves.

Whenever you expect -dealloc to be be invoked. Whenever you override -init following the convention shown in "The Objective-C Programming Language" (i.e. not taking into account the fact that it could be called more than once for the same object). Whenever you copy/paste buggy code that uses the singleton as any other object and reuse it for use with an object that's not a singleton.

(Here, history is relevant, in that in over a decade of using this pattern I cannot recall any occasion when it has caused any of the problems you suggest

http://www.cocoabuilder.com/archive/message/cocoa/2005/11/28/151235

From the consumer perspective, complexity is not affected.

The perspective I'm talking about is the writer of the singleton.

"Safety decreases" is a nebulous charge whose meaning is unclear

It requires the writer of the singleton to remember to take into account that -init may be called more than once for the same object, something very easy to forget and very easy to remain undetected because client code may actually never call alloc/init... until someday someone thinks it could actually be a good idea.

It allows code that doesn't follow the memory management rules to go by unnoticed. I consider this a problem.

if anything, though, safety is increased since the singleton cannot be prematurely disposed of (it's particularly unclear how you intend to prevent this...).

It follows from just requiring the client to follow Cocoa's memory management rules.

Moreover, you have still not, as far as I can tell, clearly and simply explained what your replacement would be (see below).

I've repeatedly stated that Uli had already done it (see above).

You talk vaguely about the possibility of allowing for the dealloc method to be called, as if this is a silver bullet.

This is no silver bullet for anything. It just lets developers to choose the approach that best fits their needs, or their programming style, or the way they want to think about their objects. There is no point in removing the ability to choose just for the sake of it.

It remains unclear how you intend to ensure that the singleton is deallocated only when it is guaranteed not to be needed again.

It is automatically ensured by just requiring client code to follow the memory management rules.

*dealloc should _not_ be used as the locus of code for doing general resource reclamation.* Other current threads have indicated why this might be the case (see, for example, <http://lists.apple.com/archives/Cocoa-dev/2005/Nov/msg02113.html>).

Actually, I already had this in mind and considered it a reason to use -dealloc for resource deallocation until garbage collection becomes available. Let me elaborate:

We cannot think of -finalize as a -doCleanUp method, because what really makes it special is that it will be _automagically_ called when the garbage collector determines that no other object keeps a reference to the instance. The closest we can get to this behavior without GC is to rely on -dealloc being called when all retained references to the object are released. This would make it easier to modify the code to take advantage of garbage collection when it becomes available, wouldn't it?

**** The following is is the important piece: ****


Please describe and show an implementation of the solution you propose. The current document basically describes two patterns (a "simple" singleton and a "true" singleton) in about three short paragraphs and 20 so lines of code. You've written many times this amount in the thread. It should be trivial, then, to provide a solution that:

Is easy to understand
Is simple to implement
Allows dealloc to be called
Ensures that dealloc is not called prematurely (to avoid expensive re-instantiation)
Prevents access of a freed object
Allows clients to abide by Cocoa's memory management rules
Allows the singleton to be accessed from any part of the application, without assuming an application architecture beyond that supplied by Cocoa
Does not impose a particular application architecture on the client

Let me know if you believe the above implementation fails to satisfy any of those requirements.

If you can do this, it can then be subjected to proper scrutiny and the debate can move forward in a useful and constructive fashion. Until then it's like tilting at ethereal windmills...

Please, note that this was already done several days ago:

http://www.cocoabuilder.com/archive/message/cocoa/2005/11/26/151142

If you wonder why this thread has gone "tilting at ethereal windmills" instead of "move forward in a useful and constructive fashion" for so long, you'll have to ask those that have kept arguing with me instead of taking a look at this implementation. :-)

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
  • Follow-Ups:
    • Re: Is Apple's singleton sample code correct?
      • From: mmalcolm crawford <email@hidden>
References: 
 >Re: Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: mmalcolm crawford <email@hidden>)

  • Prev by Date: Re: Is Apple's singleton sample code correct?
  • Next by Date: Re: Is Apple's singleton sample code correct?
  • Previous by thread: Re: Is Apple's singleton sample code correct?
  • Next by thread: Re: Is Apple's singleton sample code correct?
  • Index(es):
    • Date
    • Thread