iphone objective-c selector nsinvocation

iphone - ¿No se llama forwardInvocation?



objective-c selector (2)

Estoy teniendo problemas para avanzar en la invocación al trabajo. Por alguna razón, el tiempo de ejecución de Objective-C ignora completamente mi método forwardInvocation: y lanza una excepción de selector no reconocida

Mi código de prueba es el siguiente:

@interface InvocationTest : NSObject { } + (void) runTest; @end @interface FullClass: NSObject { int value; } @property(readwrite,assign) int value; @end @implementation FullClass @synthesize value; @end @interface SparseClass: NSObject { } @end @implementation SparseClass - (void)forwardInvocation:(NSInvocation *)forwardedInvocation { NSLog(@"ForawrdInvocation called"); FullClass* proxy = [[[FullClass alloc] init] autorelease]; proxy.value = 42; [forwardedInvocation invokeWithTarget:proxy]; } @end @implementation InvocationTest + (void) runTest { SparseClass* sparse = [[[SparseClass alloc] init] autorelease]; NSLog(@"Value = %d", [sparse value]); } @end

Estoy trabajando con información de los siguientes recursos:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105 http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html

Por lo que puedo decir, el tiempo de ejecución debería ser forwardInvocation: en la instancia de SparseClass cuando invoco [valor disperso], pero se ignora por completo:

- [SparseClass value]: selector no reconocido enviado a la instancia 0x4b1c4a0 *** Aplicación de terminación debido a la excepción no detectada ''NSInvalidArgumentException'', razón: ''- [SparseClass value]: selector no reconocido enviado a la instancia 0x4b1c4a0''


De la documentación de NSObject :

Importante: para responder a los métodos que su propio objeto no reconoce, debe anular methodSignatureForSelector: además de forwardInvocation: El mecanismo para reenviar mensajes utiliza información obtenida de methodSignatureForSelector: para crear el objeto NSInvocation que se reenviará. Su método de anulación debe proporcionar una firma de método adecuada para el selector dado, ya sea mediante la preformulación de uno o al pedirle otro objeto.

Y, a partir de la documentación en http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105 :

... si un objeto reenvía los mensajes remotos que recibe, debería tener una versión de methodSignatureForSelector: que puede devolver descripciones precisas de los métodos que finalmente responden a los mensajes reenviados; por ejemplo, si un objeto puede reenviar un mensaje a su sustituto, debería implementar methodSignatureForSelector: siguiente manera:

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector { NSMethodSignature* signature = [super methodSignatureForSelector:selector]; if (!signature) { signature = [surrogate methodSignatureForSelector:selector]; } return signature; }

Nota: vea la answer de Jilouc para la implementación correcta de methodSignatureForSelector:


También debe anular - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector para que funcione.

supongo

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { return [FullClass instanceMethodSignatureForSelector:aSelector]; }

debería estar bien.