catches in @catches (was: NSError: why returned directly?)
catches in @catches (was: NSError: why returned directly?)
- Subject: catches in @catches (was: NSError: why returned directly?)
- From: Ondra Cada <email@hidden>
- Date: Wed, 26 Apr 2006 21:03:42 +0200
On 26.4.2006, at 19:40, Jim Correia wrote:
Chris Hanson wrote about this a while ago, with examples.
http://chanson.livejournal.com/126035.html
Interesting--I haven't read the article before. Perhaps I just have
not understand the claims properly, but I regret to say I do not
agree at all with what it says (the facts and solutions are right,
but the interpretation seems to me to be wrong). Therefore, let me
elaborate and please do point out all my faults and
misinterpretations, of which there are bound to be scores :)
(i) overReleaseException *does not* overrelease anything
The code
-(void)overReleaseException { // in my opinion named quite improperly
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
[self doSomething]; // may--just as any other method--raise
[pool release];
}
is perfectly right and does not overrelease anything. The state it
leaves when exception occurred and the stack of this method is
unwound is that (a) there's an exception object held in an internal
variable (b) its r.c. is one (c) it is exactly in one release pool.
The pool's address was just the now unwound from stack and it seems
it wnet obsolete. It is not so though: the pool's address is kept in
its parent pool, and for all practical purposes from now on both the
pools can be considered one (they will be released at once).
Note: the stack now can unwind any number of similar methods (or
functions) with their own pools. It does not change anything but
there will be a "bunch" of pools, which can be considered one--all of
them will be released at once. Still, the exception (just like any
other object which might have been autoreleased in doSomething before
the exception was raised) appears in this "pool bunch" only once.
Am I wrong? If so, why? If I am right, let's go on, to the level
which catches something
(ii) when using old-style harness, there's no problem unless you make
a self-evident howler:
Since old-style harness catched always anyting (never any exception
goes up uncatched) and had no @finally, it used to be clearer what
happens--which is why I am outlining this before I'll get to the new
style:
-(void)improperOldStyleHarnessWithSimulatedFinallyAndPromotion {
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
NSException *except=nil; // to be promoted, if any
NS_DURING
[foo overReleaseException]; // it did not overrelease it. We do,
here and now
NS_HANDLER
pool=localException; // suspicious--getting local object without
retain?
NS_ENDHANDLER
[pool release]; // "finally" code here. Releasing local pool here...
[except raise]; // ... makes this promotion a self-evident bug here
}
(iii) when using new-style harness, you *have to know* what the thing
does and what it does not! (Applies for any tool, after all :))
The following code is faulty the very same way the above one is, just
it is not that self-evident:
-(void)improperNewStyleHarnessWithFinallyAndImplicitPromotion {
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
@try {
[foo overReleaseException]; // it did not overrelease it. We do,
here and now
} @finally {
[pool release];
}
}
The reason is *the same one*--a grave programmer's bug in this method
(not in the "overReleaseException" one). You just are promoting an
exception of a local pool, which you are at the same moment releasing.
Agreed that the new syntax is quite error-prone in that it hides the
problem, since the promotion happens implicitly without any extra
coding (well, have I not said quite lately I don't like the new style
very much? :))
---
Ondra Čada
OCSoftware: email@hidden http://www.ocs.cz
private email@hidden http://www.ocs.cz/oc
_______________________________________________
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