Re: Protecting singleton objects from releasing
Re: Protecting singleton objects from releasing
- Subject: Re: Protecting singleton objects from releasing
- From: publiclook <email@hidden>
- Date: Mon, 17 Feb 2003 18:49:53 -0500
On Monday, February 17, 2003, at 05:09 PM, John C. Randolph wrote:
On Saturday, February 15, 2003, at 02:38 PM, publiclook wrote:
A question was asked:
Is there any "recommended" way to protect singleton objects (e.g.
[NSProcessInfo processInfo]) from releasing? Overriding the release
method comes in mind, but I am wondering if there are better ways...
I recommend not protecting against this at all.
Can't say I agree with you here..
Reasonable people can certainly disagree.
I doubt whether any of Cocoa's singleton objects protect programmers
from inappropriately releasing them.
Actually, most of them do, and all of them *should*. The most common
technique we use in the AppKit to protect a singleton is to implement
something like:
- (id) retain { return self;}
- (id) copy { return self;}
- (unsigned int) retainCount { return UINT_MAX; }
- (void) release { }
You probably mean -copyFromZone: instead of copy and you forgot
-mutableCopyFromZone:
I think the {return self;} implementation of -copy is wrong anyway. It
is an error to copy a singleton. The code you suggest masks the error
and breaks the semantics of -copy assuming that the singleton is
mutable.
How about -(id) copyFromZone:(NSZone *)z { NSAssert(0, @"Attempt to
copy a singleton"); } ?
..in the singleton's class, which saves the overhead of looking up the
external refcounts, etc.
Find, but is the performance of releasing soemething that should not be
released a high concern ?
Instead of making -release a no-op, how about the following dealloc ?
- (void)dealloc
{
NSAssert(0, @"Attempt to dealloc a singleton");
}
If you can't live with Cocoa's memory management then don't use Cocoa.
If you use Cocoa then follow the rules and you don't need protection
from releasing singletons.
Singletons are a special case, and protecting them from being
deallocated is simply prudent coding.
-jcr
I can write the following (in mail):
+ (NSObject <FuBarProtocol> *)sharedFuBar
{
static NSObject <FuBarProtocol> *sharedInstance = nil;
if(nil == sharedInstance)
{
sharedInstance = [[FuBar alloc] init];
}
return sharedInstance;
}
Now suppose I have extended the NSApplication class via a category so
that NSApplocation conforms to the FuBar protocol. I can write the
following:
+ (NSObject <FuBarProtocol> *)sharedFuBar
{
return [NSApplication sharedApplication];
}
Now suppose I have a class that has a NSObject <FuBarProtocol> *
instance variable:
@interface FuBarStorage
{
NSObject <FuBarProtocol> *someFuBar;
}
- (void)setFuBar:(NSObject <FuBarProtocol> *)aFuBar;
- (NSObject <FuBarProtocol> *)fuBar;
@end
@implementation FuBarStorage
- (void)setFuBar:(NSObject <FuBarProtocol> *)aFuBar
{
if(aFuBar != someFuBar) {
[someFuBar autorelease];
someFuBar = [aFuBar retain];
}
}
- (NSObject <FuBarProtocol> *)fuBar
{
return someFuBar;
}
@end
The whole point is that the code for setting and getting a FuBar
instance variable should not need to know if all arguments to the set
method are singletons. there might be lots of different classes that
conform to the <FuBarProtocol> protocol. The memory management rules
are the SAME whether I am dealing with singleton or not. This is a
good thing. This reduces coupling between separate design elements.
This code is completely harmless with respect to the singleton nature
of the object being stored.
If all kinds of special log statements are added to -release, I will
get log messages when releasing is perfectly fine and I won't get any
special messages when an object is erroneously released.
The point is that releasing too many times is a bug whether the object
being released is a singleton or not. Releaseing an object the correct
number of times is NOT an error regardless of whether the object being
released is a singleton or not.
What IS an error is deallocating a singleton. If error reporting is
needed, it is in the -dealloc method of the singleton. Even there, a
log statement is not the right thing. This is a serious error that
needs an NSAssert() because the application is probably going to crash
later.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.