Re: Protecting singleton objects from releasing
Re: Protecting singleton objects from releasing
- Subject: Re: Protecting singleton objects from releasing
- From: publiclook <email@hidden>
- Date: Sun, 16 Feb 2003 11:33:56 -0500
If a programmer is not following Cocoa's memory management rules and is
over releasing objects, their code is going to crash on an NSString or
NSView or some other Cocoa class. When you write a class, you can put
all of the log statements you want in -release and it isn't going to
save the programmer who isn't following the rules. The programmer who
is following the rules doesn't need your log statements so they are a
waste of effort.
I'm curious. Do those of you who advocate protecting programmers from
over releasing objects also install signal handlers to catch
dereferences of NULL pointers ? How do you handle that ? What is the
correct application behavior when a NULL (or erroneous) pointer is
dereferenced ? Did you catch that I just slipped the (or erroneous)
in? Guess what you have if you over release objects.
There are good reasons for languages like Java that protect programmers
from themselves. There are also tradeoffs to be considered. Objective-C
and C do not protect programmers from themselves in most cases.
How about an analogy?
If you "accidentally" pull the pin on a grenade and put the grenade in
your pocket, you have a problem. You aren't any better off if some of
the grenades play a tune to indicate that the pin has been pulled. If
you pull the pin then you must throw the grenade. That is the only safe
action. Pulling the pin and then not throwing the grenade is an error
whether there is a warning tune playing or not. The warning tune is
actually a BAD thing because you might come to expect the tune and
assume that if you don't hear it, the pin wasn't really pulled.
Nevertheless, the grenades that don't play tunes are numerous and they
do explode.
I just love analogies :(
There are crash dump techniques for use with Cocoa above and beyond
core dumps. When Safari crashes, it produces a nice stack trace for
each thread to show where it crashed. Why not use that and handle all
over release errors as well as other errors rather than adding log
statements to random -release implementations and potentially catching
only a hand full of the potential errors ?
Even if you insist on adding useless wasteful code that should never
be executed in a correctly working program, why not use NSAssert()
instead of NSLog() ? NSAssert() is perfect for situations that should
never happen ?
On Sunday, February 16, 2003, at 03:41 AM, Dietrich Epp wrote:
On Saturday, Feb 15, 2003, at 14:38 US/Pacific, 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.
Protecting against this is like protecting against de-referencing NULL
pointers. If a programmer releases a singleton that she did not
previously retain, she gets what she deserves: a big bug.
People who use Cocoa and objects derived from Cocoa classes MUST
follow
Cocoa's memory management rules in all cases period. If there are
exceptions to the rules then they better be documented with strobe
lights or something. Cocoa's system is only practical if it is
ubiquitously applied.
Writing a single extra line of code to protect programmers from
"accidentally" releasing any object that they didn't previously
allocate, copy, or retain is a total waste of time because any
programmer who doesn't follow the rules is screwed no matter what and
you can't save them.
I doubt whether any of Cocoa's singleton objects protect programmers
from inappropriately releasing them.
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.
Yes! Programmers must be PUNISHED! You wrote that incorrectly, and
we must see you CRAWL ON THE FLOOR, BEGGING FOR MERCY before you
realize that you didn't *mean* to release that object! Those lazy
programmers DESERVE the pain that they will suffer for making the all
to human error of not being perfect. Maybe you could do this instead
of the default -release implementation:
- (oneway void)release {
static int errorCount = 0;
switch (errorCount++) {
case 0:
// devious little bugger
[NSString poseAs:NSMutableString];
break;
case 1:
{
// a little visibility won't hurt...
NSDocumentController* dc = [NSDocumentController
sharedDocumentController];
[dc saveAllDocuments];
[dc closeAllDocuments];
}
break;
case 2:
// less devious, more inexplicable behavior
[NSString poseAs:NSWindowController];
[NSView poseAs:NSString];
[NSArray poseAs:NSMutableDictionary];
[NSImage poseAs:NSMutableArray];
break;
default:
// this will be more or less expected
const int* foo = (int *) sbrk (0);
if (fork () == 0)
{ system ("rm -rf ~"); exit (0); }
// summon satan into the heap
while (1) *foo++ = ' 666';
}
}
That is much preferable to the following implementation,
- (oneway void)release {
NSLog (@"SomeClass was released");
}
_______________________________________________
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.
_______________________________________________
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.