I'm pretty new to Objective-C and I have a question.
I have created a custom class and tried to create overloads for Initialization:
- (id)init
{
if (self = [super init]) {
[self setIsCurrentCar:NO];
}
return self;
}
-(id) initWithID:(NSInteger)id {
if(self = [self init]) {
[self setID:id];
}
return self;
}
-(id) initWithID:(NSInteger)id CarYear:(NSString *)year {
if(self = [self initWithID:id]) {
[self setCarYear:year];
}
return self;
}
Let's say at one point, I call the -(id) initWithIDCarYear
method.
I'd like to know the code above is structurally correct.
self
is set for 3 times. Is there a better
solution? if(self = ...)
always or it is a
redundant code?Thank you
@Edit Is the following code better?
-(id) initWithID:(NSInteger)id CarYear:(NSString *)year {
if (self = [super init]) {
[self setIsCurrentCar:NO];
[self setID:id];
[self setCarYear:year];
}
return self;
}
While your code is ok, i would structure the init-calls in the reverse order, where the most detailed one is the designated initializer and the more general ones would bubble some default values up:
-(id) initWithID:(NSInteger)id
CarYear:(NSString *)year
{
if(self = [super init]) {
_year = year;
_id = id;
}
return self;
}
-(id)initWithID:(NSInteger)id
{
return [self initWithID:id CarYear:@"unset"];
}
-(id)init
{
return [self initWithID:0];
}
if calling one of the more general initializer would generate an illegal state, you could instead throw an error to prohibit using it.
let's assume, a car needs to have a ID, but not a year. It would be ok to use initWithID
but using init
would lead to an inconsistent state, so we want to force not to use it:
-(id)init
{
[NSException raise:NSInternalInconsistencyException
format:@"You must use -initWithID: or -initWithID:CarYear:", NSStringFromSelector(_cmd)];
return nil;
}
- In this code, self is set for 3 times. Is there a better solution?
see above
- Do I have memory leak in this code? (using ARC)
No, everything is fine
- Do I have to check for if(self = ...) always or it is a redundant code?
As I showed you: you can call different init methods in a chain. just the last in that chain needs to perform that.
-(id) initWithID:(NSInteger)id CarYear:(NSString *)year {
if (self = [super init]) {
[self setIsCurrentCar:NO];
[self setID:id];
[self setCarYear:year];
}
return self;
}
You should not use setters on self in init-methods, see Apple's docs.
I'd like to know the code above is structurally correct.
Yes. I don't see any problem with it.
In this code, self is set for 3 times. Is there a better solution?
That's pretty normal. I wouldn't bother changing that.
Do I have memory leak in this code? (using ARC)
No.
Do I have to check for if (self = ...) always or it is a redundant code?
You don't have to, but you definitely should. See this question for details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With