alloc e init, ¿qué es lo que hacen realmente?

¿Puede alguien explicarme qué init y alloc hacer 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?

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

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

     MyClass* myObj = [MyClass alloc]; 

    myObj no se puede usar aún, porque su estado interno no está configurado correctamente. 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 que Yannick escribió:

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

Estas sugerencias son una lección importante: nunca separe la llamada a alloc e init . No escriba:

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

porque [myObj init] puede devolver algo más. No trates de evitar esto escribiendo:

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

porque eventualmente olvidará escribir la parte myObj= en la segunda línea.

Siempre escribe:

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

Tampoco recomiendo escribir:

  MyClass* myObj = [MyClass new]; 

porque no llama correctamente al método de inicialización: algunas clases no aceptan un init simple. Por ejemplo, NSView necesita initWithFrame: que no se puede llamar con new . Entonces, no uses ninguno new tampoco.

En su forma más simple:

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

  • init: abreviatura de 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 Schedule inicializa sus canales ivar 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; } 

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

alloc asigna la memoria para crear una nueva instancia de su clase (@interface) init inicializa el contenido de esa instancia, por defecto 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 puedes escribir

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

La clase raíz de NSObject proporciona un método de clase, alloc , alloc: reserva una ubicación de memoria y devuelve el puntero a esa ubicación de memoria.

El método alloc tiene otra tarea importante, que es borrar la memoria asignada para las propiedades del objeto al establecerlos en cero.

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

no es suficiente para inicializar un objeto por completo.

Necesita 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: documentos de manzana

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