I am trying to figure out which one should be assigned an initializer and which one is a convenience initializer. I read apple docs on this topic, but I'm still not sure. Should the designated initializer have all the values ββthat are required for the class? For example, It was the first designated initializer that I created.
-(id)initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck { self = [super init]; if (self) { for(int i = 0; i<=cardCount;i++){ Card *card = [deck drawRandomCard]; if (!card) { self = nil; break; }else{ self.cards[i] = card; } } } return self; }
Now add the cardMatchMode property to this class and want to set it in the initializer. To make the class backward compatible and understand the initializers, I save the one I have and create another initializer.
-(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode { _cardMatchMode = matchMode; return [self initWithCardCount:cardCount usingDeck:deck];; }
Based on apple docs, the convenience initializer should return a value for the designated initializer, but the question is, can I set an additional property in this class in the convenience initializer? May I say that self.cardMatchMode = matchMode; Or am I not yet fully initialized?
It works, but I just wanted to understand if this is the right code, and I can access the cardMatchMode property in the convenience of init or I will need to do -(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode
as a designated initializer, and the other for the convenience of initializing and finalizing the code? Thanks!
///// Update
I was getting an error in
-(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode
When I tried to do self = [self initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck*)deck; the error says that you cannot assign yourself outside the init family. I realized what the problem is. The init method was lowercase w, and it had to be capital, so now it works. This is the code I have for the convenience initializer.
-(id)initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode { self = [self initWithCardCount:cardCount usingDeck:deck]; if (self){ _cardMatchMode = matchMode; } return self; }
Now that makes sense. I called the assigned init, which calls super, and then I set the variable cardMatchMode .
As far as I understand, there are many objects with a convenience initializer with additional parameters, and it will simply call the assigned init. If you look at NSString and it has different initializers with different parameters. This is probably an init call, which is the designated initializer. Is it correct?