ios - tus - Objective-c: Preguntas sobre self=
mis compaƱeros de trabajo hablan mal de mi (8)
@MartinR tiene una muy buena respuesta. Pero alguna vez se pregunta por qué "[super init] llama a la implementación de superclase de init con el mismo argumento (oculto). (Este podría ser el punto que entendió mal). ¿Funciona en su tercer punto?
Aquí está el extracto de la guía de Big Nerd Ranch 3ª edición, capítulo 2 Objetivo C que aclara este punto
"¿Cómo funciona el super? Por lo general, cuando envía un mensaje a un objeto, la búsqueda de un método con ese nombre comienza en la clase del objeto. Si no existe tal método, la búsqueda continúa en la superclase del objeto. La búsqueda continuará hacia arriba en la jerarquía de herencia hasta que se encuentre un método adecuado. (Si llega a la parte superior de la jerarquía y no se encuentra ningún método, se lanza una excepción).
"Cuando envías un mensaje a super, envías un mensaje a ti mismo , pero la búsqueda del método omite la clase del objeto y comienza en la superclase ".
Este código muestra cómo iOS Runtime realiza esta tarea.
objc_msgSendSuper(self, @selector(init));
He visto self = [super init]
en los métodos init. No entiendo porque ¿No [super init]
devolvería la superclase? Y si apuntamos self = [super init]
, ¿no estamos obteniendo self = superclass
?
Aquí hay un fragmento de código de ejemplo
- (id)init
{
if (self = [super init]) {
creationDate = [[NSDate alloc] init];
}
return self;
}
Espero que alguien me pueda aclarar esto. Gracias.
Cada método que declara tiene dos parámetros ocultos: self y _cmd.
El siguiente método:
- (id)initWithString:(NSString *)aString;
es convertido por el compilador a la siguiente llamada de función:
id initWithString(id self, SEL _cmd, NSString *aString);
Vea este enlace para más:
Como tiene la Pregunta self = [super init]
en la Condición if, sugiera un significado específico.
En primer lugar, [super init]
da la inicialización de la superclase de la clase existente que está en uso actualmente. El uso de [super init]
da la inicialización de la súper clase que muestra que el objeto existe de la clase.
Ahora, cuando usas self = [super init]
eso significa que estás asignando la clase al self para la utilización adicional de la misma clase.
Y al final lo pones en condición if(self = [super init])
esto significa que estás verificando si existe el objeto de la clase para evitar el comportamiento incorrecto de la aplicación.
Creo que ya está claro !!!
De la documentación de Apple :
Debido a que un método init ... puede devolver un objeto nulo o diferente al asignado explícitamente, es peligroso usar la instancia devuelta por alloc o allocWithZone: en lugar de la que devuelve el inicializador. Considere el siguiente código:
id myObject = [MyClass alloc];
[myObject init];
[myObject doSomething];
El método init en el ejemplo anterior podría haber devuelto cero o podría haber sustituido un objeto diferente. Debido a que puede enviar un mensaje a cero sin generar una excepción, no sucedería nada en el caso anterior, excepto (quizás) un dolor de cabeza de depuración. Pero siempre debe confiar en la instancia inicializada en lugar de la instancia "sin procesar" que acaba de asignar. Por lo tanto, debe anidar el mensaje de asignación dentro del mensaje de inicialización y probar el objeto devuelto desde el inicializador antes de continuar.
id myObject = [[MyClass alloc] init];
if ( myObject ) {
[myObject doSomething];
} else {
// error recovery...
}
Pensaría en ello como, iniciando todas las variables supers, etc., luego inicias tus variables de clases extendidas antes de que se devuelvan.
Self = [super init];
Según JAVA, esto significa un puntero a la instancia misma para que el objeto pueda enviarse mensajes.
La misma referencia del Ser aquí en el objetivo C,
Según JAVA, Super significa que permite acceder a la clase base o padre
Misma simulación de Super aquí en el objetivo C,
Ahora inicie la instancia para completar el proceso de inicialización.
Suponiendo que MyClass
es una subclase de BaseClass
, ocurre lo siguiente cuando llama
MyClass *mc = [[MyClass alloc] init];
-
[MyClass alloc]
asigna una instancia deMyClass
. - El mensaje de
init
se envía a esta instancia para completar el proceso de inicialización.
En ese método,self
(que es un argumento oculto para todos los métodos de Objective-C) es la instancia asignada del paso 1. -
[super init]
llama a la implementación de superclase deinit
con el mismo argumento (oculto). (Este podría ser el punto que entendiste mal). En el método
init
deBaseClass
,self
sigue siendo la misma instancia deMyClass
. Este método de inicio de superclase puede ahora- Hacer la inicialización de la base del
self
y devolver elself
, o - Descartarse, asignar / inicializar y devolver un objeto diferente.
- Hacer la inicialización de la base del
De vuelta en el método
init
deMyClass
:self = [super init]
ahora es- El objeto
MyClass
que se asignó en el paso 1, o - Algo diferente. (Es por eso que uno debe verificar y usar este valor de retorno).
- El objeto
- La inicialización se completa (utilizando el
self
devuelto por el inicio de superclase).
Entonces, si entendí tu pregunta correctamente, el punto principal es que
[super init]
llama a la implementación de superclase de init
con el argumento self
, que es un objeto MyClass
, no un objeto BaseClass
.
[super init]
es lo mismo que [ self superclass_variant_of_init]
Si desea enviar un mensaje a la superclase, hay otro enfoque (sin usar la biblioteca de tiempo de ejecución):
[[self superclass] init];