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 deforwardInvocation:
El mecanismo para reenviar mensajes utiliza información obtenida demethodSignatureForSelector:
para crear el objetoNSInvocation
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 implementarmethodSignatureForSelector:
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.