Objective-C multiple nested initWith for custom class

I am new to Objective-C and I have a question.

I created my own 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 some point I call the method -(id) initWithIDCarYear .

I would like to know that the code above is structurally correct.

  • In this code, self set 3 times. Is there a better solution?
  • Do I have a memory leak in this code? (using ARC)
  • Is it necessary to check if(self = ...) always, or is it redundant code?

thanks

@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; } 
+4
source share
4 answers

While your code is in order, I would structure the init calls in reverse order, where the assigned initializer is the most verbose, and the more general ones will be the default bubbles:

 -(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 initializers will result in an illegal state, you can throw an error instead to prohibit its use.

Suppose a car must have an identifier, but not a year. It would be nice to use initWithID , but using init will result in an inconsistent state, so we want to force it not to be used:

 -(id)init { [NSException raise:NSInternalInconsistencyException format:@"You must use -initWithID: or -initWithID:CarYear:", NSStringFromSelector(_cmd)]; return nil; } 

  • In this code, self is set 3 times. Is there a better solution?

see above

  • Do I have a memory leak in this code? (using ARC)

No, everything is okay

  • Do I need to check if there is always (self = ...) or redundant code?

As I showed you: you can call different init methods in a chain. only the last in this chain should accomplish this.


 -(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 seters on self in init methods, see Apple docs .

+8
source

I would like to know that the code above is structurally correct.

Yes. I do not see any problems with this.

In this code, self is set 3 times. Is there a better solution?

This is pretty normal. I would not change that.

Do I have a memory leak in this code? (using ARC)

No.

Is it necessary to check whether the code is always (self = ...), or is the code redundant?

You do not have to, but you definitely must. See this question for more details.

+3
source

It looks like you have one required initialized variable and two that are actually optional.

I would recommend using the init method and two @property () for identifier and carYear. This reduces the number of initializers and better reflects this contract for using the class.

+2
source

From my little knowledge ... tried to create overloads for Initialization this statement should not be used here.

As usual, overload means the same name with several arguments, but in obj-c we do not follow this. When obj-c is overloaded, faking is done by naming parameters.

So, you have 3 different sets of code, and each of them is called a different method. And you do not have a memory leak, because you do not allocate memory three times for the same object, instead you initialize it.

+1
source

All Articles