- Only return nil (in an initializer) if you can't perform the initialization. If a caller passes your initializer a path to a file that does not exist and the object can't work without a file it would make sense to return nil.
- Don't return nil if you can find a nice "workaround" for a problem during initialization such as replacing a missing argument with a sensible default value.
- If you want to return nil and you haven't sent a initialization message to super yet perform the following steps:
- cleanup any resources you may have created,
- call [self release]; and then
- return nil
- If you want to return nil and already have sent a initialization message to super (which returned nil) perform the following steps:
- cleanup any resources you may have created,
- return nil
#import "Person.h"
enum {
PersonErrorCodeFirstLastNameNotValid = 0
};
typedef NSInteger PersonErrorCodes;
@implementation Person
@synthesize firstName, lastName;
- (id)initWithFirstName:(NSString *)initFirstName
lastName:(NSString *)initLastName
error:(NSError **)error {
if(initFirstName == nil || initLastName == nil) {
if(error != NULL) {
NSMutableDictionary *u = [NSMutableDictionary dictionary];
[u setValue:@"first/last name not valid."
forKey:NSLocalizedDescriptionKey];
PersonErrorCodes c = PersonErrorCodeFirstLastNameNotValid;
*error = [NSErrorerrorWithDomain:@"com.example.unique"
code:c
userInfo:u];
}
[self release];
return nil;
}
self = [super init];
if(self != nil) {
self.firstName = initFirstName;
self.lastName = initLastName;
}
returnself;
}
- (id)initWithFirstName:(NSString *)initFirstName
lastName:(NSString *)initLastName {
return [self initWithFirstName:initFirstName
lastName:lastName
error:NULL];
}
- (id)init {
return [self initWithFirstName:[NSString string]
lastName:[NSString string]];
}
- (void)dealloc {
self.firstName = nil;
self.lastName = nil;
[super dealloc];
}
@end
As you can see, this class has three initializers: -init, -initWithFirstName:lastName: and -initWithFirstName:lastName:error:. The designated initializer is -initWithFirstName:lastName:error:, which is used by a caller which is interested in the cause of a failed initialization. -initWithFirstName:lastName: can be used by a caller which only wants to create a Person and see if it worked or not.