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: Andy Lee <email@hidden>
- Date: Tue, 29 Nov 2005 21:28:09 -0500
On Nov 29, 2005, at 8:11 PM, Jeff Laing wrote:
Minor discussion at cross-purposes here, I feel.
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)
Thanks for pointing this out. I was only thinking about the second
suggestion, and completely missed the first.
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?
If you have a -doCleanUp method in your class, then to program really
defensively you should have all methods be aware of the fact that
they might be called while the object is in a post-cleanup state.
This includes -doCleanUp itself, which may need to be careful not to
do the cleanup twice. The methods could try to exit gracefully, or
they could throw an exception, or they could NSLog(). In any case,
there will need to be extra logic.
One thing that just occurred to me -- if you take the app delegate
approach, you should call a *class* method to do the cleanup, to deal
with the case where the singleton's never been instantiated. If you
have a -doCleanUp instance method, then your app delegate is going to
have a line like this:
[[MyClass sharedInstance] doCleanUp];
If the singleton was never instantiated, this will force it to be
instantiated -- possibly an expensive operation -- just so it can be
cleaned up. If you use a class method for cleanup, then your app
delegate can do this:
[MyClass doCleanUp];
The logic within +doCleanUp can then be a no-op if the singleton was
never instantiated.
On the other hand, isn't it as clear as:
"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.
Good point. And it isn't just that Apple says it; it's a good
practice in general carried over from C: whoever does the malloc()
should do the free().
Now, if you have an "internal" cleanup (ie, you don't tell the
singleton to
cleanup, it works it out for itself by listening to notification), the
ball-game is different. Then, I don't see any reason not to put it
all in
release.
I assume you mean -dealloc? What if your object is in a retain
cycle? Then -release won't by itself ever call -dealloc. You need
some other method whose job it is to break the cycle.
But I'd be inclined to have my notification listener send [self
release] then NSLog() loud and clear if the singleton didn't actually
disappear, to catch the external retain problem.
I'm not sure why the NSLog(), and why external retains are a problem
if they've been properly balanced? At the time you receive the
notification, you don't know who else might still legitimately be
retaining the object, especially since AFAIK notifications aren't
guaranteed to be in any particular order.
Its going to remain fairly subjective as to whether "good design"
involves
maintaining as clear a boundary as possible between your classes,
or tying
them together in a mesh of inter-operating notifications.
I think you're right. It seems like any approach you choose will
have potential pitfalls. The only thing I'd say for sure is, if you
have a method called +sharedInstance, then please use Cocoa-style
singletons. Also, as I said before, document the need to do cleanup,
and the proper way to do it in your case.
--Andy
_______________________________________________
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