ios objective-c initialization

ios - Inicializador designado e inicializador de conveniencia en Object-c y cómo crearlos correctamente y vincularlos



objective-c initialization (2)

De acuerdo con la documentación de Apple, el initalizador designado

es típicamente el método init ... que tiene la mayoría de los parámetros y que hace la mayor parte del trabajo de inicialización.

Entonces en su caso esto será - (id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode . Todos los demás inicializadores tendrán menos argumentos, llenando los parámetros que faltan en el inicializador designado con valores predeterminados o de otro modo inferidos.

Entonces, cada inicializador de conveniencia llama al inicializador designado en lugar del inicializador de la superclase.

El par inicializador designado por conveniencia se verá así en su caso:

/** Convenience initializers */ - (id)init { self = [self initwithCardCount:kDefaultCardCount usingDeck:[Deck defaultDeck] cardMatchMode:kCardMatchModeDefault]; return self; } - (id)initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck { self = [self initwithCardCount:cardCount usingDeck:deck cardMatchMode:kCardMatchModeDefault]; if (self) { } return self; } /** Designated initializer */ - (id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode { 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; } } // Set card match mode here: _cardMatchMode = matchMode; } return self; }

Estoy tratando de entender cuál debe ser el inicializador designado y cuál es el inicializador de conveniencia. Leí documentos de Apple sobre ese tema, pero todavía no estoy seguro. ¿El inicializador designado debe tener todos los valores que se requieren para la clase? Por ejemplo
Este fue el primer inicializador designado que creé

-(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; }

Ahora cardMatchMode propiedad cardMatchMode a esta clase y me gustaría configurarla en el inicializador. Para hacer que la clase sea compatible con versiones anteriores y para entender los inicializadores, me quedo con el que tengo ahora y creo otro inicializador.

-(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode { _cardMatchMode = matchMode; return [self initWithCardCount:cardCount usingDeck:deck];; }

Según los documentos de Apple, el inicializador de conveniencia debe devolver el valor del inicializador designado, pero la pregunta es ¿puedo establecer la propiedad adicional en esta clase en el inicializador de conveniencia? ¿Puedo decir self.cardMatchMode = matchMode; o el yo todavía no está completamente inicializado?
Funciona pero solo quería entender si este es el código correcto y puedo acceder a la propiedad cardMatchMode en la conveniencia init o tendría que hacer -(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode

como el inicializador designado y el otro, ¿es conveniente iniciar y volver a trabajar el código? ¡Gracias!

/////Actualizar

Me estaba dando un error en el

-(id)initwithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode

Cuando intenté hacer self = [self initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck*)deck; el error dice que no puedes asignar yo fuera de la familia init. Me di cuenta cuál era el problema. El método init tenía w minúscula y tenía que ser mayúscula, por lo que ahora funciona. Este es el código que tengo ahora para mi inicializador de conveniencia.

-(id)initWithCardCount:(NSUInteger)cardCount usingDeck:(Deck *)deck cardMatchMode:(NSUInteger)matchMode { self = [self initWithCardCount:cardCount usingDeck:deck]; if (self){ _cardMatchMode = matchMode; } return self; }

Ahora tiene más sentido. Llamé al init designado que llama super y luego establecí la variable cardMatchMode .

Por lo que yo entiendo, hay muchos objetos que tienen un inicializador conveniente con parámetros adicionales y solo se llamará init designado. Si miras NSString y tiene diferentes inicializadores con diferentes parámetros. Probablemente esté llamando a init, que es el inicializador designado. ¿Es esto correcto?


El inicializador designado es el que invoca el inicializador designado de la clase superior de su clase, por lo que es el único inicializador que invoca un método en el objeto super . Ningún otro inicializador en la clase debería hacer eso; estos inicializadores secundarios deben invocar el inicializador designado usando self . Normalmente, el inicializador designado tiene todos los parámetros necesarios para crear un objeto útil de la clase.

En resumen, el inicializador designado es el único que invoca un inicializador en super , y todos los demás inicializadores en la clase invocan el inicializador designado (usando self ).