1. ¿Cuál es el comportamiento normal en Objective-C si usted llama a un método en un objeto (puntero) que es igual a cero (tal vez porque alguien se olvidó para inicializar)? No debería generar algún tipo de error (error de segmentación, excepción de puntero nulo…)?
  2. Si este comportamiento es normal, hay una manera de cambiar este comportamiento (mediante la configuración del compilador), de modo que el programa plantea algún tipo de error /excepción en tiempo de ejecución?

Para hacerla más clara de lo que estoy hablando, he aquí un ejemplo.

Tener esta clase:

@interface Person : NSObject {

    NSString *name;

}

@property (nonatomic, retain) NSString *name;

- (void)sayHi;

@end

con esta aplicació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 en el programa puedo hacer 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
InformationsquelleAutor Florin | 2010-04-23

3 Comentarios

  1. 63

    Un mensaje enviado a un nil objeto es perfectamente aceptable en Objective-C, es tratado como un no-op. No hay manera de bandera como un error, porque no es un error, en realidad puede ser una característica muy útil de la lengua.

    De la docs:

    El envío de Mensajes a nil

    En Objective-C, es válido para enviar un
    mensaje para nada—simplemente, no tiene efecto
    en tiempo de ejecución. Hay varios patrones
    en el Cacao que tomar ventaja de esta
    hecho. El valor devuelto de una
    mensaje a nil también puede ser válido:

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

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

      Si aPerson‘s spouse es nil,
      luego mother es enviado a nil y la
      método devuelve nil.

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

    • Si el método devuelve un struct, tal como se define por el Mac OS X ABI
      Llamada a la función de Guía para ser devueltos en
      se registra un mensaje enviado a
      nil devuelve 0.0 para cada campo
      la estructura de datos. Otros struct
      tipos de datos no se llena con
      ceros.

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

    • Y yo no soy consciente de ninguna manera para cambiar este comportamiento. Es una parte fundamental de la programación con el Objetivo-C/Cacao. Usted va a aprender a amarla.
    • Enlace a doc en respuesta está muerto (No se Encontró la Página).
    • Actualizado doc enlace (Archivado): developer.apple.com/library/archive/documentation/Cocoa/…. Búsqueda De Working with Nil.
    • El enlace a documento ha sido actualizado
  2. 13

    De Greg Parker‘s sitio:

    Si se ejecuta el Compilador LLVM 3.0 (Xcode 4.2) o posterior

    Mensajes a cero con el tipo de retorno | retorno 
    Enteros de hasta 64 bits | 0 
    De punto flotante a largo doble | 0.0 
    Punteros | nil 
    Las estructuras de | {0} 
    Cualquier _Complex tipo de | {0, 0} 
    
  3. 6

    Una cosa que usted debe tener claro es que en Objective-C, que usted no llamar a un método en un objeto, enviar un mensaje a un objeto. El tiempo de ejecución se encuentra el método y la llame.

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

Dejar respuesta

Please enter your comment!
Please enter your name here