• 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: Thu, 1 Dec 2005 18:27:21 +0100

On 30 Nov 2005, at 02:11, Jeff Laing wrote:

I think whats being suggested by about 30% of the participants in this
thread is that the singleton register itself to listen for the
notifications.

I believe David is *not* suggesting this, but rather that your application
logic listen for the notification and call an appropriate method on the
singleton to tell it to go away. (Or perhaps have the application delegate
do it - either approach would work)

Actually I've always had both approaches in mind and I've strived to not make this explicit until now on purpose. This issue is tough if you want to consider it from a general point of view, and the level of misunderstanding in this thread already was high enough.

The real issue here is possible cleanup dependencies. Resources may need to be disposed of in a certain order. An object managing certain resources may depend on the services provided by another object to do its own cleanup.

If I've correctly understood the way notifications work, you have little or no control at all over the order in which they will be received. That means that if you have two objects that have registered for the notification and one of them depends on the other to do its job first, then you are in trouble. Also, you may not like the idea of having to add notification registering and handling to every object whose resources must be properly disposed of.

So you may want to centralize all notification registering and handling for application termination in a single object (e.g. the application delegate). But this approach has its own share of problems as well. The method responsible for scheduling the cleanup becomes coupled with object dependencies it probably shouldn't have to be aware of. Also, the object responsible to do the cleanup may be a singleton that you don't (and shouldn't have to) know whether it has actually been instantiated or not.

So, in the general case, you have to consider both approaches (maybe in the same application) and handle both of them properly.

It is true that using [singleton release] instead of [singleton doCleanUp]
is more sensitive to coding problems elsewhere in your application - but if
you are going to argue that sort of theoretical scenario, what happens to
the objects that have erroneously retain'd the singleton if they try to
access it *after* the doCleanUp message was delivered - which they might do
during their own cleanup processing?

Actually, I would say it's the other way around. The only things you should be concerned with using the [singleton release] approach are the same things you would be concerned with if the singleton was an ordinary object, namely adherence to memory management rules and cyclic references. The retain/release facilities provided by the framework provide a consistent and uniform approach to handle cleanup dependencies as any other dependency. With the [singleton doCleanUp] approach, you have to separately take care of cleanup dependencies yourself.

Consider, for example, the (supposedly problematic) case when sending [singleton release] wouldn't actually deallocate the singleton because some other object still keeps a (retained) reference to it. What this means (or should mean, if there is no bug) is that the object that retains the singleton actually depends on the singleton "being there" for whatever it does. Now, what happens if this object actually needs the singleton to do its own cleanup? Someone must ensure that neither the singleton itself nor the resources it manages are released before this object does its own cleanup. But who? And more important, why? Why should that extra level of coupling be added when retain/release would get you this for free?

Sending [singleton release] when the singleton is being retained by some other object is not the problem, it's the solution. The problem is that some other object still needs the singleton (and its resources) and you don't (shouldn't have to) know whether that other object actually depends on the singleton (and its resources) being there to do its own cleanup.

Because of the absence of runtime support mechanisms for automatic handling of object dependencies, for the above to work properly you must make object dependencies explicit by sending the appropriate -retain/-release messages when such dependencies exist, even if you know that the object is a singleton.

Note that this is not a limitation of the [singleton release] approach. If there is indeed a cleanup dependency, with the [singleton doCleanUp] approach you'll have to devise your own retain/release-equivalent mechanism to handle it as well. You can look at the -release message as a deferred -doCleanUp message. Note also that the memory management rules explicitly say that you _must_ retain any instance returned by +sharedInstace if you need to count on the instance "being there" outside the scope of the method that called +sharedInstace.

"Apple say you should not release something you didn't
{alloc|retain}"

As such, the external request to "cleanup" really shouldn't be done via
release, if you are trying to play by the memory usage rules.

#if !RUNTIME_SYSTEM_HAS_GARBAGE_COLLECTOR
[[MySingleton sharedInstance] release];
#endif

This makes it explicit that you know what you are doing, that the reason you're doing it is a limitation of the runtime system and that this code can safely be removed when (and if) the limitation gets fixed.

By doing things such as this, you become less dependent on the limitations of the development environment. You can leverage universally applicable design patterns and idioms you've learned in other environments which didn't have such limitations. Moreover, your code is ready to take advantage of the removal of such limitations as soon as they get fixed. This does not preclude you from taking advantage of any advanced cutting-edge features that your development environment might actually have. It's the limitations that you should avoid your design to be tied to.

Note: I was considering the centralized cleanup scheduling case here, which means either you know that the singleton has indeed been instantiated or you have some way of knowing without actually instantiating it (e.g. the singleton class has a +hasBeenInstantiated method).

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>
    • Re: Is Apple's singleton sample code correct?
      • From: glenn andreas <email@hidden>
    • Re: Is Apple's singleton sample code correct?
      • From: Greg Titus <email@hidden>
  • Prev by Date: Problem with setNeedsDisplay: in derived NSOpenGLView
  • Next by Date: Re: Is Apple's singleton sample code correct?
  • Previous by thread: Re: Problem with setNeedsDisplay: in derived NSOpenGLView
  • Next by thread: Re: Is Apple's singleton sample code correct?
  • Index(es):
    • Date
    • Thread