• 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: Ondra Cada <email@hidden>
  • Date: Tue, 29 Nov 2005 10:17:01 +0100

David,

On 29.11.2005, at 0:51, David Gimeno Gost wrote:

Lets at least adhere to the conventions of the memory management provided by the framework, whether singleton or not.

More or less all others are trying to point out to you that's exactly what the overriding of memory management methods achieves.

No, overriding those methods does not achieve that. There is no need to override those methods to achieve that.

There is.

Presume we, for any godforsaken reason, *need* that the singleton contract ("there is at most one") is fulfilled even if it happens to be accessed through the standard alloc/init combo (note please I do not advocate we need this all the time, quite the contrary -- I say we need that pretty rarely, but we may).

If so, we just have to re-implement alloc, init, or both -- for obvious reasons.

Presume further we don't want the singleton to die at all (or, at the very least, not till the application is about to quit -- I'll get back to it in a moment). Again, of course, it may not be the case with some particular singleton class; nevertheless, in my experience, this would be normally (though of course not always) exactly what we need: more often than not the singleton, along with other tasks, keeps some settings and values which, once set up, should not vanish before the application quits (and not all of them belong to the default database or other external storage, either). Sure, you can store them in statics: ugly design, quite non-necessary, caused only by the original design flaw (i.e., letting the singleton to die whilst the app lives on).

So in this case, we have to mess up the retain/release/dealloc combo too(*), lest the only one who happened to alloc/init the singleton releases it, and the thing goes poof -- far before we may need it again.

(*) Of course, can be done also without overriding retain/release/ dealloc e.g. by overretaining in init. For all practical reasons that's exactly the same.

What I am aiming at is *this is what we have to do to adhere to Cocoa memory-management conventions*, whilst keeping the immortable singleton contract as well.

You get the correct behavior by just requiring client code to follow Cocoa's memory management rules.

No you don't. Correct client would first alloc/init the singleton, then release it. Unless someone other did the same, and unless we did some trick singleton-level (be it reimplementation of retain/release/ dealloc or overretaining or whatever), the singleton goes poof. That's *not* what we wanted: we want it to survive infinitely (or at the very least till app is about to quit).


Actually, overriding those methods allows client code to break Cocoa's memory management rules without a hitch.

Sure it allows. *So what*? The memory management rules (heck, *any* reasonable rules in the wide world!) just say: do it this way, and it's all right. There is ***no*** contract which says that if you do it otherwise, the app would crash.


(The most obvious example is a forgotten (auto)release: that is a violation of the memory management rules all right, but the application runs without a glitch; it leaks memory a bit, but unless the object in question is big or tooo many of them and/or the app runs for a long long time, nobody ever notices.)

Back to business: making the class to adhere to memory management rules means exactly this:

** if the client follows the rules, the class does exactly what we want it to do **

Namely: singleton is created on demand the first time, shared the next time, and never dies. [*] Without overriding retain/release/ dealloc (or other trick with the same outcome) it would not apply. In other words, our singleton *would not* adhere to the memory management rules. [*]

(Note that it's not a bug per se -- many singletons do not, since their programmers just know they won't be used the standard way. That's quite another story.)

And note that at least in theory we don't give a tinker's cuss what happens if the client does *not* follow the rules. Sure, it may be worth to get defensive, protoect before the more frequent bugs (overreleasing comes to mind) at least by logging out something like "If you see this log, put a breakpoint to fooBarOverReleased to see what's wrong". But again, that's another story, which is *completely* irrelevant to singletons.

+sharedInstance { static id myself=nil; if (!myself) myself=[[self alloc] init]; return myself; }

That's a very valid *singleton* we just made here. It does not quite adhere to the memory-management conventions though, or rather, it does, alas breaking so the contract of being a singleton :)

It doesn't? Why?

Since [*] ... [*] above.

Anyway, to use the *object deallocation* tool -- the dealloc method -- for the *application quit clean-up* -- is plain wrong. You are just using a completely inappropriate tool;

Why?

Most often than not, disposal of resources should be decoupled from application quit cleanup. App-quit cleanup is one possible reason certain resources must be disposed of in a certain way, but it may not be the only one. Moreover, you don't want to have to know whether it's the only one. The object that manages the resources shouldn't be concerned with the reasons those resources should be disposed of. All the object should be concerned with is that it is no longer needed (for whatever reasons) and, thus, the resources it manages should be disposed of properly.

Not quite. There are different kinds of resources, and they are to be released a different way in different moments. For example, it is completely nonsensical to release the memory when the process is about to end.


This is what -dealloc accomplishes. You just tell the object that manage the resources that you no longer need it.

That's nice from the theoretical point of view. In practice though, it brings more problems than advantages.


app-quit cleanup is a very very different beast from object deallocation.

And 'for' loops also are a very different beast, but that doesn't mean you shouldn't use them to do the cleanup, does it?

It does, for HOM is better :D

Analogically, whilst you *can* tweak dealloc to do your application termination cleanup, you should not. It's ugly, error-prone, it makes maintenance a bitch. If I want to see what exactly my application with hundreds of source files in a number of lodable bundles and subprojects does before quit, I grep for NSApplicationWillTerminateNotification, and that's that. What would you do, check *all* them deallocs, whether some of them may contain more code than plain [ivar release]?

There is nothing wrong about _using_ object deallocation to do the app-quit cleanup.

There's all wrong with it. I did it, long ago. I've learnt the hard way.

Disposal of resources by means of the destruction of the objects that manage them is a well-known widely-used design pattern in object oriented software development (not just C++).

Incidentally, C++ and object oriented are two things with nothing in common :)
---
Ondra Čada
OCSoftware: email@hidden http://www.ocs.cz
private email@hidden http://www.ocs.cz/oc



_______________________________________________ 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: David Gimeno Gost <email@hidden>
    • Re: Is Apple's singleton sample code correct?
      • From: Serge Cohen <email@hidden>
References: 
 >Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: Shawn Erickson <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: Uli Kusterer <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: Uli Kusterer <email@hidden>)
 >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>)
 >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>)
 >Re: Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: Christian Brunschen <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: glenn andreas <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: Ondra Cada <email@hidden>)
 >Re: Is Apple's singleton sample code correct? (From: David Gimeno Gost <email@hidden>)

  • Prev by Date: Re: [NSApp mainMenu] returns nil under 10.4.3
  • Next by Date: Re: [NSApp mainMenu] returns nil under 10.4.3
  • 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