Re: [super dealloc] when init fails. Was: Logging pointer EXC_BAD_ACCESS?
Re: [super dealloc] when init fails. Was: Logging pointer EXC_BAD_ACCESS?
- Subject: Re: [super dealloc] when init fails. Was: Logging pointer EXC_BAD_ACCESS?
- From: Quincey Morris <email@hidden>
- Date: Sun, 29 May 2011 13:03:00 -0700
On May 29, 2011, at 12:20, Jerry Krinock wrote:
> - (id)initWithDocUuid:(NSString*)docUuid {
> NSManagedObjectContext* moc ;
> moc = [[BkmxBasis sharedBasis] exidsMocForIdentifier:docUuid] ;
>
> self = [super initWithManagedObjectContext:moc
> entityName:constEntityNameStarxid] ;
> if (!self) {
> [super dealloc] ;
> }
>
> return self ;
> }
To review, there are three points of possible failure in an init method:
- (id) init... {
// do some preparatory things
if (...preparatory things failed...) {
... error point #1 ...
}
self = [super init...];
if (!self)
... error point #2 ...
// do rest of initialization
if (...something goes wrong...) {
... error point #3 ...
}
Error point #2 is easy. Just return nil.
#3 is pretty easy. Clean up things you've already done in this method (such as allocating memory), and invoke '[super dealloc]' before returning nil. This is still slightly risky, because the super dealloc *could* end up invoking some (override) method in this subclass, which -- not having been successfully initialized -- could crash. But it's still the best choice, and you should try to remember to code your subclass defensively, if you think this situation might occur.
#1 is the hard one. You can't return nil, because that would leak the object's memory. You can't call super's dealloc, because you don't know if super's dealloc is safe to call if super's init hasn't executed. You can't call release, because that might call dealloc. You can't free the object's memory yourself, because you don't know how (unless you happen to know how it was allocated, which in general you don't).
The best choice in a case like this is to avoid doing anything that might fail before calling the super init. Or, throw an exception if it fails. Or, call one of super's designated initializers anyway, then call super dealloc after it returns. Or, I suppose, you could do the least wrong of all the wrong things, which would probably be to return nil and leak the object deliberately.
But I don't really know a good answer for case #1.
_______________________________________________
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