2012-04-13 7 views
12

En un libro, vi que si una subclase es reemplazar el método de una superclase, podemos tener¿Por qué en Objective-C usamos self = [super init] en lugar de solo [super init]?

self = [super init]; 

En primer lugar, se supone que esto se haga en el método de la subclase init?

En segundo lugar, me pregunto por qué la llamada no es sólo

[super init]; 

? Quiero decir, en el momento de llamar al init, la memoria está asignada por alloc ya (creo que por [Foobar alloc] donde Foobar es el nombre de la subclase. Así que ¿no podemos simplemente llamar a [super init] para inicializar las variables miembro? ¿Por qué tenemos que obtener el valor de retorno de init y asignar a self? Quiero decir, antes de llamar a [super init], self debe apuntar a un mandril de asignación de memoria válida ... ¿por qué asignar algo a uno mismo otra vez?

(si la asignación, no lo hará solo [super init] devolver el valor existente self?)

+3

http://cocoawithlove.com/2009/04/what-does-it-mean-when-you-assign-super.html –

+1

@AndreasCarlbom brillante tutorial gracias ... – Krishnabhadra

+0

posible duplicado de [¿Por qué debería llamar? self = \ [super init \]] (http://stackoverflow.com/questions/2956943/why-should-i-call-self-super-init) –

Respuesta

10

¿Por qué asignar el valor devuelto por [super init] a sí mismo? En cuanto a un método de inicialización típica:

- (id)initWithString:(NSString *)aString { 
    self = [super init]; 
    if (self) 
    { 
     instanceString = [aString retain]; 
    } 
    return self; } 

¿Por qué asignamos [súper init] a uno mismo aquí?

La razón se debe a que los libros de texto [súper init] está autorizado a hacer una de tres cosas:

  1. devolver su propio receptor (el puntero del auto no cambia) con heredadas valores de instancia inicializan .
  2. Devuelve un objeto diferente con valores de instancia heredados inicializados.
  3. Retorno nulo, lo que indica un error.

En el primer caso, la asignación no tiene efecto en sí mismo y la instanceString está activado en el objeto original (la línea instanceString = [unaCadena retener]; podría haber sido la primera línea de el método y el resultado sería el mismo).

En el tercer caso, la inicialización ha fallado. self se establece en nil, no se toman más medidas y se devuelve nil.

La justificación de la asignación a la libre está asociado con el segundo caso : si el objeto devuelto es diferente, queremos que el:

instanceString = [aString retain]; which gets converted to 

self->instanceString = [aString retain]; to act on the correct value, 

así que tenemos que cambiar el valor del auto para que apunte a esta nueva objeto.

esperanza de que esto ayude ...

From Cocoa with Love

+0

interesante ... así que si 'self' apuntaba a algunos memoria asignada, y luego 'self' se establece en' nil', entonces es como ... hacerse a sí mismo como una especie de fantasma? Por ejemplo, si se trata de un objeto 'Duck', entonces' duck' apunta a una memoria válida asignada, con variables miembro, pero ahora, cuando 'self' se establece en' nil', entonces se convierte en un fantasma, como correcto ahora ya no tiene variables miembro (no apunta a ninguna memoria asignada), y todo lo que queda son los métodos, la capacidad de ejecutar código sin ninguna "sustancia". –

+0

NINGÚN objeto debería soltarse ... la forma normal de hacerlo es llamando al -dealloc .. –

2

Es posible la superclase podría decidir que el objeto no se puede inicializar correctamente y devolver cero como una falla. Si no asigna nil a self, su método init continuará bajo la suposición de que la clase padre ha inicializado correctamente el objeto.

También es posible que la clase principal también devuelva un objeto completamente diferente si lo desea.

2

entender que el objeto está puntos auto ya alloced y una memoria.

Ahora [super init] hace la parte de inicialización.

1) Si la inicialización tiene éxito auto puntos a un mismo objeto antes de la inicialización

2) Si la inicialización es función de fallo de init devuelve nil y auto = nil. Ahora podemos comprobar si el objeto es inicializado y en caso afirmativo hacer nuestra magia por este código

if(self = [super init]){ 
    // do our magic 
} 

Es igual que utilizamos un imageView, que normalmente usan

UIImageView imgView = [[UIImageView alloc] init]; 

imgView sólo tendrá no nula valor si tanto alloc como init son exitosos.

3

Un ejemplo clásico de devolución de un objeto diferente desde -init es la implementación de un clúster de clase: una interfaz abstracta con múltiples implementadores concretos que proporcionan almacenamiento o algoritmos diferentes. +[NSString alloc] devuelve una instancia de NSPlaceholderString. Los iniciadores de la instancia de marcador de posición inspeccionan sus parámetros, liberan la cadena de marcador de posición y devuelven una instancia inicializada de una subclase de concreto NSString.

Cuestiones relacionadas