2011-09-26 11 views
19

Estoy investigando sobre Objective-C, y me gustaría saber si tiene el concepto de reflexión. Ninguno de los documentos que he encontrado hasta ahora describe la reflexión.¿Objective-C tiene reflejo?

+0

Consulte http://en.wikipedia.org/wiki/Objective-C –

+1

Objective-C tiene una capacidad de reflexión mucho más poderosa que Java. Puede obtener más información de [Guía de programación en tiempo de ejecución Objective-C de Apple.] (Http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008048) – venj

+0

gracias "ott" y "venj". –

Respuesta

24

Hay funciones de tiempo de ejecución descritas en Runtime Reference que permiten no solo consultar las características de una clase o instancia, sino también agregar un método o incluso crear una nueva clase en tiempo de ejecución. Digo que este es un tipo muy dinámico de reflexión, que generalmente no estaba disponible para los lenguajes basados ​​en C. Mike Ash's wrappers es un contenedor Objective-C alrededor de eso. De nuevo, ¡puede incluso agregar métodos! La clase base de Cocoa, NSObject, también proporciona envoltorios para muchas de las funciones de tiempo de ejecución, consulte NSObject protocol reference. Por ejemplo

 [foo respondsToSelector:@selector(bar:)]; 

    if([foo isKindOfClass:[NSString class]]){ ... } 

hace lo que dicen los nombres de los métodos. Incluso puede agregar un método sobre la marcha.Por ejemplo,

#import <Foundation/Foundation.h> 
    #import <objc/runtime.h> 

    @interface Foo:NSObject 
    { 
    } 
    @end 
    @implementation Foo 
    -(void)sayHi 
    { 
     NSLog(@"Hi! from %@",NSStringFromSelector(_cmd)); 
    } 
    +(BOOL)resolveInstanceMethod:(SEL)sel 
    { 
     Method method=class_getInstanceMethod(self,@selector(sayHi)); 
     class_addMethod(self,sel,method_getImplementation(method),method_getTypeEncoding(method)); 
     return YES; 
    } 
    @end 

    int main(){ 
    NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init]; 
     Foo* foo=[[Foo alloc] init]; 
     [foo aeiou]; 
     [foo bark]; 
     [foo mew]; 
     [pool drain]; 
     return 0; 
    } 

Esto produce la salida

Hi! from aeiou 
    Hi! from bark 
    Hi! from mew 

Lo que hace es como sigue:

  1. SEL es la variable que representa el mensaje enviado (o llamada a un método, en el otra terminología)
  2. Objective-C runtime llama a resolveInstanceMethod: de una clase si un mensaje enviado a una instancia no se implementa nted en la clase
  3. Entonces, en este caso, simplemente copio una implementación de un método predefinido llamado sayHi a la implementación de ese método.
  4. Desde el método, puede usar _cmd para ver cuál fue el selector utilizado al llamar al método. Entonces, incluso desde una única implementación sayHi, podemos obtener resultados diferentes.

Algunas de las implementaciones estándar de Cocoa (clave-valor-codificación, clave-valor-observación y datos centrales en particular) utilizan el tiempo de ejecución para modificar dinámicamente la clase.

1

Supongo que no sé qué aspecto de la reflexión estás buscando. ¿Estás buscando cómo determinar qué clase es una variable dada? Si es así, mira esto: Objective-C class -> string like: [NSArray className] -> @"NSArray"

// Get a object's class name 
if ([NSStringFromClass([foo class]) compare:@"NSSomeObject"] == NSOrderedSame) {...} 

// Does an object have a method 
[foo respondsTo:@selector(method:)] 

¿Usted está buscando algo más que esto?

+0

¡oh! mi gerente requiere investigación sobre Clase abstracta y Reflexión en Objetivo-C. Traté de averiguarlo pero no obtuve ningún resultado, así que debo preguntarle a todos :(. P/S: muchas gracias. –

+0

¿Está relacionado con su trabajo? Tiene que pagarnos parte de su salario :) – Yuji

+0

@ Yuji. jeje. ok: P –

1

Hay una bandada de methods que puede acceder a varias propiedades de una clase y, presumiblemente, "peek" y "poke" en algunas partes internas del objeto. Nunca he jugado con ellos, y una pequeña lectura que he hecho sugiere que están lejos de ser perfectos, pero parecen ofrecer cierta capacidad de "reflexión", similar al concepto de Java.

+0

muchas gracias :) –

+0

¿Tiene alguna idea de cómo establecer la propiedad real una vez que la ha encontrado utilizando Reflection? Tengo una pregunta aquí: http://stackoverflow.com/q/25538890/1735836 – Patricia

11

Sí, Objective-C tiene reflexión (y clases abstractas). Si esa reflexión se ajusta a sus necesidades o no es una pregunta diferente.

La reflexión en Objective-C es sorprendentemente flexible para un lenguaje derivado de C. Puede preguntar a una clase qué métodos implementa o puede modificar y/o agregar métodos a las clases existentes. Incluso puede crear nuevas clases sobre la marcha o cambiar la clase de cualquier instancia en cualquier momento.

Un programa típico de Objective-C no hace ninguna de las tesis cosas (al menos directamente) a excepción de vez en cuando o llamando respondsToSelector:conformsToProtocol:. Si bien Objective-C es un lenguaje completamente dinámico, reflexivo y orientado a objetos, eso no significa que dichos patrones se fomenten o se usen de manera típica.

Usted puede encontrar mis respuestas a estas preguntas interesantes:

In Objective C, how to find out the return type of a method via reflection?

Does Objective-C have a Standard Library?

Smalltalk runtime features absent on Objective-C?

Y, por supuesto, la duración es very well documented. Como es the language. O podría read the source.

+0

¿Tiene alguna idea de cómo establecer la propiedad real una vez que la ha encontrado utilizando Reflection? Tengo una pregunta aquí: http://stackoverflow.com/q/25538890/1735836 – Patricia

Cuestiones relacionadas