Pregunta

Objetivo-C utiliza dinámica de unión:. Es decir llamadas de método se resuelven en tiempo de ejecución

Bella.

uso de la notación de punto realmente se reduce a una llamada al método

Pero, ¿por qué entonces, no puedo hacer algo como esto:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


  // Intercept the exception
  @try
  {
    @throw [ NSException 
            exceptionWithName:@"Exception named ME!" 
            reason:@"Because i wanted to" 
            userInfo:nil ] ;
  }
  @catch( id exc ) // pointer to an exception object?
  {



    //NSLog( @"%@ : %@\n", exc.name, exc.reason ) ; // ILLEGAL:  Request for member 
    // 'name' in something not a structure or union..
    // If objective-c uses dynamic binding, and dot notation
    // boils down to calling the getter, then
    // WHY do I have to cast to the concrete type here?

    // Only works if I cast to the concrete type NSException*
    NSException* nexc = (NSException*)exc ;
    NSLog( @"%@ : %@\n", nexc.name, nexc.reason ) ;



  }



  [pool drain];
    return 0;
}

Cuando escucho "enlace dinámico" Estoy pensando en "lo que debe comportarse como un lenguaje de script", y me sorprende la forma inflexible Objective-C parece comparación con un lenguaje de script como JavaScript .

¿Fue útil?

Solución

Se está confundiendo el tiempo de ejecución y el compilador. El tiempo de ejecución no tiene problemas para hacer frente a eso. La cuestión es que la notación de puntos (que es el azúcar sintáctico) requiere escribir información para el compilador para eliminar la ambigüedad entre objetos Objetivo-C y estructuras C.

Si no se utiliza la notación de puntos funciona:

NSLog( @"%@ : %@\n", [exc name], [exc reason]) ;

Lo anterior generará una advertencia si el tipo no es de identificación ya que el compilador sabe que sabe el tipo y no puede garantizar el envío va a funcionar, pero va a compilar y ejecutar.

En el fondo de la cuestión que nos ocupa es el compilador necesita saber si se debe generar una carga de la estructura, o un despacho de Objective C, en otras palabras, con la notación de puntos que debe tener suficiente información para determinar la diferencia entre un objeto y un escalar tipo.

Otros consejos

Enlace dinámico no es sinónimo de tipado dinámico . C es un lenguaje fuertemente tipado y, en particular, del tipo de un valor de argumento o de retorno es crítica y puede afectar significativamente la generación de código.

Propiedades están específicamente diseñados para eliminar la ambigüedad. Como parte de eso, se tomó la decisión de no Permitir la sintaxis con punto para ser utilizado en contra id.

En concreto, se aborda esta situación:

@interface Foo
- (short) length;
@end

@interface Bar
- (unsigned long long) length;
@end

Teniendo en cuenta lo anterior en dos ficheros de cabeceras, compilación de [anObject length] dará una advertencia sólo dos archivos de cabecera se han importado . Si sólo hay un archivo de cabecera se ha importado, entonces el sitio llamada será compilado devolver el tipo que se ve en la cabecera. Si el sitio llamado fuera por el otro método, un resultado muy inesperado serían devueltos.

La limitación de la sintaxis con punto elimina esta ambigüedad potencial. Esta es también la razón por la que no en general, ver las declaraciones co-variantes de métodos. El C ABI simplemente no lo soporta de forma inadecuada (una vez dicho esto, Objective-C hace un trabajo pobre de apoyar tipo de objeto co-varianza).

En realidad, los desarrolladores de Objective-C rara vez se utiliza el tipo de id. declaraciones de tipos específicos permiten al compilador para mejorar significativamente su código de validación.

Objetivo-C es compatible con enlace dinámico. Sin embargo, no puede utilizar las propiedades de los objetos de tipo 'id' - pero se puede enviar cualquier mensaje que desee. (Esto es probablemente un error en la definición actual / aplicación ... Pero dejemos eso de lado por ahora.)

Si lo hizo

NSLog(@"%@ : %@", [exc name], [exc reason] ); 

a continuación, que funcionaría. Tenga en cuenta que no es necesario poner una nueva línea en una declaración NSLog, ya que todos están en líneas separadas de todos modos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top