How to clean up memory when custom init fails
When my custom initializer fails, I am supposed to return nil. What is the convention for cleaning up any memory I've allocated in my initializer, that I was expecting would be cleaned up in dealloc?
Here is a contrived example:
- (id)init
{
if ((self = [super init])) {
instanceVar1 = [[NSString alloc] initWithString:@"blah"];
if (bad_thing_oh_noes) {
return nil;
}
}
return self;
}
- (void)dealloc
{
[instanceVar1 release];
[super dealloc];
}
A more realistic circumstance where I can't efficiently check every error conditi开发者_运维问答on before I do allocations would be deserializing a complex object containing arrays and the like.
Anyway, do I clean up the allocated memory before returning nil, do I send a dealloc message to self before returning nil, or is all of this managed for me magically?
If an error occurs during an initializer, you should call release
on self
and return nil
.
if (bad_thing_oh_noes) {
[self release];
return nil;
}
Also, you must make sure that it is safe to call dealloc
on a partially initialized object.
You should call release
only at the point of failure. If you get nil
back from the superclass’s initializer, you should not call release
.
Normally, you should not throw an exception upon initialization failure.
An example from Handling Initialization Failure:
- (id)initWithURL:(NSURL *)aURL error:(NSError **)errorPtr {
self = [super init];
if (self) {
NSData *data = [[NSData alloc] initWithContentsOfURL:aURL
options:NSUncachedRead error:errorPtr];
if (data == nil) {
// In this case the error object is created in the NSData initializer
[self release];
return nil;
}
// implementation continues...
精彩评论