punteros puntero objeto ejemplos iphone objective-c initialization null-pointer

iphone - ejemplos - Llamar a un método en un objeto no inicializado(puntero nulo)



ejemplos de punteros en c# (3)

Desde el sitio de Greg Parker :

Si ejecuta LLVM Compiler 3.0 (Xcode 4.2) o posterior

Messages to nil with return type | return Integers up to 64 bits | 0 Floating-point up to long double | 0.0 Pointers | nil Structs | {0} Any _Complex type | {0, 0}

  1. ¿Cuál es el comportamiento normal en Objective-C si llama un método en un objeto (puntero) que es nulo (quizás porque alguien olvidó inicializarlo)? ¿No debería generar algún tipo de error (falla de segmentación, excepción de puntero nulo ...)?
  2. Si se trata de un comportamiento normal, ¿hay alguna manera de cambiar este comportamiento (configurando el compilador) para que el programa genere algún tipo de error / excepción en el tiempo de ejecución?

Para dejar más claro de lo que estoy hablando, aquí hay un ejemplo.

Tener esta clase:

@interface Person : NSObject { NSString *name; } @property (nonatomic, retain) NSString *name; - (void)sayHi; @end

con esta implementación:

@implementation Person @synthesize name; - (void)dealloc { [name release]; [super dealloc]; } - (void)sayHi { NSLog(@"Hello"); NSLog(@"My name is %@.", name); } @end

En algún lugar del programa, hago esto:

Person *person = nil; //person = [[Person alloc] init]; // let''s say I comment this line person.name = @"Mike"; // shouldn''t I get an error here? [person sayHi]; // and here [person release]; // and here


Un mensaje enviado a un objeto nil es perfectamente aceptable en Objective-C, se trata como un no-op. No hay forma de marcarlo como un error porque no es un error, de hecho puede ser una característica muy útil del lenguaje.

De los docs :

Envío de mensajes a cero

En Objective-C, es válido enviar un mensaje a nil, simplemente no tiene ningún efecto en el tiempo de ejecución. Hay varios patrones en Cocoa que aprovechan este hecho. El valor devuelto por un mensaje a nil también puede ser válido:

  • Si el método devuelve un objeto, entonces un mensaje enviado a nil devuelve 0 ( nil ), por ejemplo:

    Person *motherInLaw = [[aPerson spouse] mother];

    Si el spouse es nil , entonces se envía a la mother a nil y el método devuelve nil .

  • Si el método devuelve cualquier tipo de puntero, cualquier número entero escalar de tamaño inferior o igual a sizeof(void*) , float , double , long double o long long , entonces un mensaje enviado a nil devuelve 0 .

  • Si el método devuelve una struct , tal como se define en la Guía de funciones de la función ABI de Mac OS X, para que se devuelva en los registros, un mensaje enviado a nil devuelve 0.0 para cada campo en la estructura de datos. Otros tipos de datos struct no se llenarán con ceros.

  • Si el método devuelve algo distinto a los tipos de valores antes mencionados, el valor de retorno de un mensaje enviado a cero no está definido.


Una cosa que debe tener claro es que en Objective-C, no llama a un método en un objeto, envía un mensaje a un objeto. El tiempo de ejecución encontrará el método y lo llamará.

Desde las primeras versiones de Objective-C, un mensaje a nil siempre ha sido una operación segura no operativa que devuelve nada. Hay un montón de código que depende de este comportamiento.