2010-10-03 20 views
21

¿Alguien me puede explicar qué hacen init y alloc en Obj-C? Estoy leyendo este libro obj-c que da un ejemplo de creación de objeto pero realmente no entra en detalles de lo que hace. ¿Qué devuelve alloc? ¿Qué devuelve init?alloc y init, ¿qué es lo que realmente hacen?

Animal * k = [Animal alloc]; 
k = [k init]; 

Respuesta

35
  • alloc asigna un trozo de memoria para contener el objeto y devuelve el puntero.

    MyClass* myObj = [MyClass alloc]; 
    

    myObj no se puede utilizar, sin embargo, debido a su estado interno no está correctamente configurado. Por lo tanto, no escriba un código como este.

  • init establece la condición inicial del objeto y lo devuelve. Tenga en cuenta que lo que devuelve[a init]puede ser diferente de a. Eso explica el código Yannick escribió:

    -init{ 
        self=[super init]; // 1. 
        if(self){   // 2. 
         .... 
        } 
        return self;  // 3. 
    } 
    
    1. En primer lugar, es necesario llamar a la superclase de init, para configurar las variables de instancia de la superclase, etc.Puede devolver algo que no sea igual al original self, por lo que debe asignar lo que se devuelve al self.
    2. Si self no es nulo, significa que la parte controlada por la superclase está correctamente inicializada. Ahora realiza su inicialización. Todas las variables de instancia están configuradas en nil (si es un objeto) y 0 si es un número entero. Tendrá que realizar configuraciones iniciales adicionales.
    3. Devuelve la configuración self. ¡El self devuelto puede ser diferente de lo que se asigna! Por lo tanto, debe asignar el resultado de init a su variable.

Esta sugerencia una lección importante: no dividir la llamada a alloc y init. No escriba:

MyClass* myObj = [MyClass alloc]; 
[myObj init]; 

porque [myObj init] podría devolver algo más. No trate de evitar esto mediante la escritura:

MyClass* myObj = [MyClass alloc]; 
myObj=[myObj init]; 

porque es muy probable que se olvide de escribir la parte myObj= en la segunda línea.

siempre escribir:

MyClass* myObj = [[MyClass alloc] init]; 

Asimismo, no se recomienda escribir:

MyClass* myObj = [MyClass new]; 

porque no llama correctamente el método de inicialización: algunas clases no acepta una llanura init. Por ejemplo, NSView necesita initWithFrame:, que no se puede llamar con new. Por lo tanto, no use new tampoco.

+0

¡Buena explicación! Gracias –

+2

Dicho esto, si no necesita un '-init' personalizado, puede llamar definitivamente a' + new'. Si miras la implementación de '+ (id) new', es literalmente' return [[self alloc] init]; ' –

+0

Tengo una pregunta, Yuji. La variable myObj es un puntero a la ubicación de la memoria ¿verdad? Su punto "Primero, necesita llamar al init de la superclase, configurar las variables de instancia de la superclase, etc. Eso puede devolver algo que no es igual al auto original", entonces ¿quiere decir que en la superclase se asigna un nuevo objeto de nuevo debido a que el puntero a la ubicación de la memoria cambia? –

3

En su forma más simple:

  • alloc: abreviatura de la asignación, reservers una posición de memoria y devuelve el puntero a la ubicación de la memoria. Este puntero se almacena en la variable k.

  • init: corto para la inicialización, configura el objeto y devuelve el objeto. El método init depende del objeto, pero generalmente implica enviar el mensaje init a la superclase. Y si ese método init (de la superclase) devuelve un objeto (no nulo) se pueden configurar algunos ivars dependiendo de la tarea de esa clase.

-

ejemplo de una implementación init, la clase Horario inicializa su Ivar canales con una matriz vacía. Básicamente, le está dando al objeto Schedule la oportunidad de solucionarse por sí mismo, de modo que pueda comenzar a recibir mensajes una vez que se haya creado. Podría eliminar la inicialización de canales del método init, pero luego debería verificar si los canales ivar son nulos en todos los métodos de la clase Schedule e inicializarlos si es nulo.

- (Schedule*)init { 
    self = [super init]; 

    if (self) { 
    channels = [[NSMutableArray alloc] initWithCapacity:0]; 
    } 

    return self; 
} 
+0

¿qué establecer el objeto significa? ¿qué vuelven? – denniss

+0

He extendido mis respuestas un poco. –

1

alloc e init son dos métodos que se heredan de NSObject puede proporcionar a sus propios métodos o llamar a los de NSObject

alloc asigna la memoria para crear una nueva instancia de la clase (@interface) init inicializa el contenido de esa instancia, de manera predeterminada init establece todos los valores de miembros en 0/nil, sin embargo, puede crear su propio método init para personalizar lo que se hace.

Animal * k = [[Animal alloc] init]; // creates a new Animal object 

también se puede escribir

Animal * k = [Animal new]; // which would be a bit more similar to other languages 
-1

Alloc asignará la memoria para el objeto, pero Init coloca el objeto en la memoria y establece los valores predeterminados.

+0

explica tu respuesta por favor. – Irfan

0

El NSObject clase raíz proporciona un método de clase, alloc, alloc: reservers una posición de memoria y devuelve el puntero a la ubicación de la memoria.

El método alloc tiene otra tarea importante, que consiste en eliminar la memoria asignada para las propiedades del objeto estableciéndolas en cero.

Esto evita el problema habitual de memoria que contiene la basura de lo que estaba almacenado antes, pero es

no lo suficiente como para inicializar un objeto completo.

es necesario combinar una llamada a alloc con una llamada a init , otro método NSObject:

  • (id) init; El método init es utilizado por una clase para asegurarse de que sus propiedades tengan valores iniciales adecuados en la creación. La forma correcta de asignar e inicializar un objeto es anidar la llamada de alloc dentro de la llamada a init, así:

    ClassName * objectName = [ClassName alloc] init];

de: manzana documentos

Cuestiones relacionadas