2011-01-29 8 views
6

lo que tengo entendido, un método sin aplicarse se resuelve de la siguiente manera:¿Qué determina el proceso por el cual se resuelven los métodos no implementados?

  1. resolveInstanceMethod:/resolveClassMethod: para crear una oportunidad de poner en práctica el método
  2. forwardingTargetForSelector: para crear una oportunidad de enviar a un delegado
  3. forwardInvocation: tiene la posibilidad de manejar el método como lo considere oportuno.

¿Dónde se define este proceso de tres pasos? Me gustaría manejarlo porque NSInvocation podría ser demasiado pesado para mis necesidades. He tenido un poke alrededor de la fuente de tiempo de ejecución y realmente no puedo ver nada.

Parece que el viejo tiempo de ejecución llamaría adelante: args: en el receptor, para hacer esto pero parece que se ha ido del nuevo. Supongo que el proceso debe ser definido por el framework en lugar del tiempo de ejecución, ya que sería extraño si el tiempo de ejecución dependiera de Cocoa hasta el punto de requerir que NSInvocation maneje los mensajes. ¿Es quizás un método no documentado el que recibe un llamado en NSObject/NSProxy?

Editar:

Parece que el tiempo de ejecución declara, pero nunca define, una función C que se llama cuando objc_msgSend no puede encontrar una aplicación:

id objc_msgForward(id object,SEL message,...);

I don' t trabajo para Apple, así que no sé cómo Foundation lo implementa, pero al menos en el caso de Cocotron, usan:

id objc_msgForward(id object,SEL message,...) 
{ 
    Class  class=object->isa; 
    struct objc_method *method; 
    void  *arguments=&object; 

    if((method=class_getInstanceMethod(class,@selector(forwardSelector:arguments:)))!=NULL) 
     return method->method_imp(object,@selector(forwardSelector:arguments:),message,arguments); 
    else 
    { 
     OBJCRaiseException("OBJCDoesNotRecognizeSelector","%c[%s %s(%d)]", class_isMetaClass(class) ? '+' : '-', class->name,sel_getName(message),message); 
     return nil; 
    } 
} 

añadiendo un método forwardSelector:arguments: parece que no funciona, así que supongo que esto es específico de Cocotron. ¿Alguien sabe lo que hace objc_msgForward en Foundation?

+0

¿Cuáles son sus necesidades y por qué cree que 'NSInvocation' es demasiado pesado para ellas? Aconsejaría no reinventar la rueda a menos que haya encontrado definitivamente que 'NSInvocation' le está ralentizando. –

+0

Escribo algo parecido a un lenguaje de scripting que utiliza el reenvío de mensajes para interactuar con objective-c. Por ahora, estoy usando NSInvocation, pero podría terminar haciendo esto miles de veces por segundo, por lo que la sobrecarga sería notable. Pero supongo que también tengo curiosidad ... –

+1

FWIW, objc_msgForward() se implementa en el ensamblaje según la plataforma/arquitectura de destino: http://opensource.apple.com/source/objc4/objc4-437.1/runtime/ Messengers.subproj/ –

Respuesta

6

estoy escribiendo algo un poco como un lenguaje de script que utiliza mensaje reenvío para interactuar con Objective-C. Por ahora, estoy usando NSInvocation, pero podría terminar en haciendo esto miles de veces por en segundo lugar, por lo que la sobrecarga sería perceptible. Pero supongo que también soy sólo curiosidad ...

En lo que se refiere a reenvío de mensajes, el comportamiento es [a menudo sutilmente] diferentes a través de diferentes plataformas y versiones de tiempo de ejecución.

En cualquier caso, no reinvente la rueda. Hay dos puentes de idiomas disponibles en la actualidad que se acercan bastante al puente de fidelidad completa desde el que puede aprender muchísimo. Ambos tienen licencias liberales específicamente para permitir tal reutilización.

Específicamente, el proyecto MacRuby ofrece una implementación de Ruby que se sienta encima de CoreFoundation y el Objective-C Garbage Collector. Es el puente "más nativo" disponible (y no es terriblemente portátil como resultado, no es un objetivo del proyecto).

El puente PyObjC es el mejor ejemplo disponible de un puente de alta fidelidad entre el tiempo de ejecución de Objective-C y el tiempo de ejecución de otro lenguaje de OO dinámico; Pitón.Es un poco más portátil, aunque los bits que no son Mac OS X probablemente se hayan podrido un poco.

(Sería negligente al no mencionar F-Script;? Una nueva lengua construida en Objective-C para el que, según creo, la fuente es/estaba disponible)

Todos los puentes se ocupan al mismo método Aprovisionamiento, subclases y proxys de tiempo de ejecución cruzada, todos los cuales parecen aplicables a sus necesidades particulares.

+0

Las fuentes de F-Script están dentro del mismo archivo .zip que contiene la distribución binaria en http://www.fscript.org. – millenomi

+0

El código fuente de F-Script también está disponible en GitHub: https://github.com/pmougin/F-Script – 0xced

+0

Buena llamada. No había pensado en eso. –

Cuestiones relacionadas