Re: Core Data debugging
Re: Core Data debugging
- Subject: Re: Core Data debugging
- From: Quincey Morris <email@hidden>
- Date: Thu, 16 Jul 2009 17:44:50 -0700
On Jul 16, 2009, at 16:49, Timothy Wood wrote:
So, as an example, I might want do do something like:
- (BOOL)saveSomething:(NSError **)outError;
{
NSData *data = build some data;
if ([data writeToFile:path options:someOptions error:outError])
return YES;
OBError(outError, ErrorCodeEnum, @"some reason", ... other user
info k/v pairs ...);
return NO;
}
...
- (BOOL)saveSomething:(NSError **)outError;
{
NSData *data = build some data;
// strawman, remember, I'd not do it this way… =)
[defaults setObject:data forKey:someKey];
if ([defaults synchronize])
return YES;
OBError(outError, ErrorCode, @"some reason", ... other user info k/
v pairs ...);
return NO;
}
Well, now I'm screwed due to these NSError rules. I'm reading
*outError for an optional chained NSUnderlyingError and it might be
trash.
Sure, I should remember to ignore it or initialize it to nil myself
or have a OBBaseError macro, but one day I'll forget. The current
rules make me write more and more fragile code than I'd need to if
we could just all depend on setting NSError locals to nil before
passing them down. I know we can't right now, but I'm saying that
makes life harder than it could be. Cocoa is supposed to round off
the rough corners in programming! =)
Well, it's a valid but terribly weak argument, if you don't mind my
suggesting so.
In the second case, you're not screwed because of "these NSError
rules" but because you're using an output parameter of the method as
an input parameter to the macro. It's a plain bug, unless you assert
it not to be a bug (which is basically what you're doing, which is why
I'm calling it "weak").
But your example is weak for another reason. If the methods were this
simple, you'd be unlikely to leave outError uninitialized in the
second method. It's only going be be an issue in a longer method that
does a series of things that can fail, and then you're more likely to
write:
if (![... do something ... error: outError]) {
OBError (outError, ...);
return NO;
}
if (![... do something else ... error: outError]) {
OBError (outError, ...);
return NO;
}
...
and if there's something to do that doesn't return a NSError:
if (![... do something ...]) {
OBError (nil, ...);
return NO;
}
What's so fragile about that? If you paste it somewhere else, the
'nil' goes with it. :) Is the return-YES-on-success pattern really
reasonable for most non-trivial methods?
I should confess my bias here. I'm a big fan of Wil Shipley's
"mainline" code approach:
http://www.wilshipley.com/blog/2005/07/code-insults-mark-i.html
but you have to scroll down a bit to find it:
What you should really do is write "if" statements that check for
improperconditions, and if you find them, bail. This cleans your
code immensely, in two important ways: (a) the main, normal
execution path is all at the top level, so if the programmer is just
trying to get a feel for the routine, all she needs to read is the
top level statements, instead of trying to trace through indention
levels figuring out what the "normal" case is, and (b) it puts the
"bail" code right next to the correctness check, which is good
because the "bail" code is usually very short and belongs with the
correctness check.
(But ignore the part further down where he goes right off the rails
about self = [super init]. :) )
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden