2012-08-25 21 views
5

He estado siguiendo una serie de tutoriales y me estoy cayendo con uno mismo. ¿Alguien puede ayudar, por favor?Entender el "yo" y configurar uno mismo al súper

Tengo el siguiente init, que es un método de instancia.

- (id) initWithScore:(int) s { 
    self = [super init]; 

    if (self) { 
     score = s; 

    } 

    return self; 
} 

Ahora, leyendo el código establecí el self en el superinicio, por lo que el self ahora apunta a super. Luego compruebo si self es válido y establezco una puntuación igual al valor que envié en mi InitWIthScore. Tengo esto hasta ahora.

Pero ahora vuelvo self que apunta a la súper, entonces ¿cómo estoy devolviendo mi subclase?

Por lo tanto, digamos que alguien llama a mi clase que pasa en 100, mi código es devolver el súper, no la clase, ¿cómo funciona? ¿Cómo el código de llamada tiene un valor de 100 en la puntuación?

por supuesto, sí lo hace el trabajo pero no tengo ni idea de por qué :-(

Respuesta

5

Este constructo permite al inicializador (el inicializador super y el que está escribiendo) con una forma de falla - nil se devuelve si el objeto no se puede inicializar. También es por eso que marca nil en su init después de llamar al super.

Ambos self y super apuntan a la misma estructura de datos en la memoria, es decir, el objeto que ha asignado.La diferencia está en la semántica del lenguaje de estos punteros especiales:

Cuando se usa self, el compilador de Objective-C iniciará el método y la resolución de sobrecarga en su tipo actual.

Cuando se usa super, el compilador Objective-C iniciará el método y la resolución de sobrecarga en el súper tipo inmediato de su clase. En otras palabras, super es solo una semántica para poder llamar a un método en su súper clase aunque exista el mismo método en su clase actual.

En otras palabras (ligeramente simplificado), super trata de la ubicación de la memoria como si fuera una instancia de la superclase (por ejemplo, el tipo que subclases, a menudo NSObject), mientras que self trata de la ubicación de la memoria como un puntero regular a la tipo que has definido.

Si imprime super y self en el depurador, verá que apuntan a la misma ubicación de memoria.

+0

¡genial !, eso es lo que estaba buscando ... Tan en mí mismo :-) eso es bueno, ¿pero también en mí? ¿Aunque super sería la superclase? es decir, NSObject? – Martin

+0

tan self = [super init]; ahora self es igual a mi súper clase de NSObject, o es igual a mí, pero ahí es donde me confundo, viene de un fondo .net/java. Si llamo a mi súper clase y hago un init, entonces el súper es en realidad nsobject, ¿no es – Martin

+0

@Martin, actualicé un poco la respuesta, espero que aclare. Si tiene una clase 'Foo' que hereda' NSObject', 'Foo' también es' NSObject' - la relación is-a. 'self' y' super' apuntan a la misma memoria pero la trata diferente al resolver. – driis

3

Toda la llamada de creación de objetos se ve un poco como esto:

SomeClass *foo = [[SomeClass alloc] initWithScore:100]; 

Ahora, la primera cosa que sucede es llamar [SomeClass alloc]. Esto creará una estructura para SomeClass en la memoria y devolver un puntero a ella. Luego viene la materia inicialización, donde self es el puntero de la etapa anterior. por lo tanto self puntos a un objeto de clase SomeClass.

La asignación se ve un poco extraño, sin embargo:

self = [super init]; 

En la mayoría de los casos no va a cambiar [super init]self, sólo se devolverá el puntero creado por [SomeClass alloc]. Pero el patrón de asignación permite dos opciones adicionales:

  1. La superclase init puede indicar un error de construcción mediante la devolución de nil, en cuyo caso todos los siguientes inicializadores rescatar y obtener un objeto nil.

  2. El inicializador de la superclase puede decidir devolver un puntero self diferente, por ejemplo, si se realiza un caché complicado. El puntero debe apuntar nuevamente a un objeto de tipo SomeClass, para que su código funcione (puede acceder a score, etc.).

Sugiero que lea The How and Why of Cocoa Initializers por Mike Ash. Y sí, es muy bueno darse cuenta de que self y super apuntan al mismo objeto, como señaló driis.

+0

Creo que él quiere saber por qué lo hace de todos modos. La razón para esto es que '[super init]' puede devolver un puntero diferente, por ejemplo 'nil' si no se inicializa a sí mismo. – JustSid

+0

Hola zoul, sí, tengo la creación del objeto y entiendo lo que no entiendo (ver el fragmento de código en cuestión más arriba) es que en el initiWithScore, el auto se está asignando a [superinicio] por lo que ahora tiene el super y devuelve este super al cliente llamante, entonces, ¿cómo tiene el cliente llamante (su código) el contenido de "SomeClass" cuando se devolvió super. – Martin

+0

Gracias por el enlace Zoul, hace una lectura interesante. – Martin

Cuestiones relacionadas