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: Mon, 28 Nov 2005 19:35:13 +0100
On 28 Nov 2005, at 09:10, Christian Brunschen wrote:
One can never be certain that any application will actually be
properly terminated
Yes. And that's precisely the reason you shoud strive to have a uniform
and consistent way of disposing of resources, no matter how your
application terminates, no matter when. Destructors (or whatever they
are called in any particular OO language) are widely considered the
best way to provide such a uniform and consistent approach. I'm not
going to argue here why they are indeed the best approach.
- consider application crashes, or if a user 'force quits' or 'kills'
the program in question.
Yes, consider those cases and then tell me please what can you do about
it without destructors that you couldn't do with them. Or, put another
way, tell me what destructors preclude you from doing about it that
having your clean up procedures scattered throughout your code
wouldn't.
Thus, classes should be written such that they, and their instances,
can gracefully handle that situation - i.e., the situation where they
themselves are not involved in their own cleanup, and thhe cleanup is
instead done by the system.
The whole point of object oriented software development is that classes
shouldn't be written that way. Actually, classes _cannot_ be written
that way. There is no way they can gracefully handle that situation and
there is no way the cleanup can be done by the system without breaking
encapsulation, which is one of the goals object oriented software
development strives to achieve, and for good reasons.
Yes, and there is nothing in the approach I'm suggesting that
prevents client code from continuing to do that. What makes it
different is that, in addition to that usage, client code would have
the option to properly deallocate the object if (and when)
appropriate.
But who decides 'when appropriate'?
There are really two issues here: life-cycle and object deallocation.
If we were talking any other object oriented language with support
mechanisms for automatically and transparently handling object
destruction (e.g. C++, Java, Eiffel), then this issue wouldn't even be
considered because everyone would agree that object deallocation is
_always_ mandatory when the life-cycle of the object ends, and the
runtime system indeed guarantees this when possible (i.e. if the
application doesn't crash). I assert that, even if the language does
not provide such support mechanisms, we should still strive to
accomplish it in our code, if for no other reason because it allows us
to think about it and keep using idioms and design patterns in a more
language-independent manner.
This leaves us with the question of who decides what the life-cycle of
the object (which can never exceed that of the application it belongs
to) should be, and the answer depends on the purpose of the singleton
and its performance requirements. In most cases, as has already been
stated repeatedly in this thread, the only reason to keep the object
alive until the application quits are performance requirements, so this
decision belongs to the application, not to the singleton itself, and
it happens that just requiring client code to follow Cocoa's memory
management rules is enough to ensure this is what will happen, so there
is really no reason to override all those methods. The only thing you
accomplish doing that is preventing the singleton "destructor" from
ever being called, something IMO you should never do in any OO
language.
One point of a singleton is that the client code is not involved in
making the creation
Agree.
or destruction decisions about the singleton
Disagree. Object oriented languages without support mechanisms for
properly and transparently handling object destruction allow you to do
this, but there is no way you can avoid it in Objective-C. You can fake
it and pretend that you are not doing it by putting your clean up code
somewhere else, thus breaking encapsulation or defining superfluous
methods whose only purpose is to do what -dealloc should do, but you
can't avoid it.
- from the point of view of the client coode, the cingleton is
'always there'.
Client code shouldn't care whether the singleton is always there, just
as it shouldn't care how it's created. All it should care is how to get
access to the object. Just requiring that client code follows Cocoa's
memory management rules is enough to ensure that the object will
"always be there".
Usually a singleton is lazily created the first time a client actually
asks for it, and then kept around foor the lifetime of the
application, as has been noted. If one were to allow destriction of
singletons, for instance by allowing their retain count to drop to
zero, then we have a situation where two distinct, non-overlapping
uses of a singleton in thhe same program, would lead to two different
singleton instances being created and then deallocated:
You have completely missed the point. This has already been discussed
to death and several possible implementations have been shown to
demonstrate that this is not the case. Sample code has been provided
for two of them. It's all in the archives, I'm not going to discuss it
again.
Now, if the singleton, as quite frequently is the case, requires a
fair amount of resources to instantiate, then your suggested pattern
could lead to significantly worse performance than the traditional
pattern, as in the traditional pattern a single instance would be
allocated and kept around for the life of the application, whereas
with your pattern there could be an arbitrary number of 'singletons'
(each with distinct, non-overlapping lifespans)that would be created
and destrooyed through the lifetime of the application.
Wrong. I've never proposed anything like that, it wouldn't be a
singleton, which is what we are talking about here. Please see the
archives if you are really interested in making any sense of this
discussion.
Your pattern is more one of a 'serial singleton' - a class of which
either none, or at most one, will be in use at any given time, but
whose life cycle is not intended to be conceptually infinite. This is
not a pattern that I have come across much before. However I would say
that it is conceptually firmly _different_ from that which is
generally known as a 'singleton'.
If I was really suggesting what you think I'm suggesting I would agree
with you. But that's not the case.
with your pattern, you can have an arbitrary number of such
instantiations, though you will never have more than one instance
actiive at the same time.
Wrong. The only way to have the singleton object instantiated more than
once is by breaking Cocoa's object management rules. You don't need to
override the retain/release methods to accomplish that. This has
already been discussed to death.
I was talking in relative, not absolute, terms. The number of methods
that don't have to be overridden if the constraint is removed is more
than half the total number of methods that need to be overridden if
the constraint is maintained.
But by 'removing the constraint'you are changing one of the generally
accepted behaviours of a singleton.
Wrong. The constraint I'm talking about is the one that says that the
singleton's destructor should never be called. That at most one
instance of it will ever be created follows from just requiring client
code to follow Cocoa's memory management rules (which it should do
anyway), there is no need to add the constraint to ensure this.
If you want something that behaves differently, then by all means do
so, but don't try to shoehorn it into something that already has a
well-defined behaviour from which your suggested behaviour differs. In
other words, go ahead and use your pattern, but please do it in such a
way as to minnimize confusion:
Actually, the confusion comes from somewhere else. What I'm (was)
trying to do is precisely to remove what IMO is causing that confusion.
[snipped a lot of comments based on wrong assumptions and
misunderstandings of what I've been saying in this thread.]
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