2011-01-06 31 views
19

Ich habe Probleme, vorwärts zu kommen, um zu arbeiten. Aus irgendeinem Grund ignoriert die Objective-C-Laufzeit vollständig meine forwardInvocation: -Methode und löst eine nicht erkannte Selektorausnahme aus.forwardInvocation wird nicht aufgerufen?

Mein Testcode ist wie folgt:

@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 

Ich arbeite Informationen aus den folgenden Quellen aus:

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

Soweit ich sagen kann, ist die Laufzeit sollte Aufruf forwardInvocation: auf der Instanz von SparseClass, wenn ich [Sparse-Wert] aufrufen, aber es wird vollständig ignoriert:

- [SparseClass Wert]: unerkannte Selektor Instanz gesendet 0x4b1c4a0 *** app Abschluss aufgrund abgefangene Ausnahme 'NSInvalidArgumentException', Grund: '- [SparseClass Wert]: unerkannte Selektor Beispiel 0x4b1c4a0 gesendet'

Antwort

36

Sie müssen auch - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector überschreiben, damit es funktioniert.

Ich denke,

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

ok sein sollte.

+1

Super! Lief wie am Schnürchen. – Karl

24

Von der NSObject Dokumentation:

Wichtig: Um zu Methoden zu reagieren, die das Objekt selbst nicht erkennt, Sie methodSignatureForSelector: zusätzlich zu forwardInvocation: außer Kraft setzen müssen. Der Mechanismus zum Weiterleiten von Nachrichten verwendet Informationen, die von methodSignatureForSelector: erhalten werden, um das NSInvocation Objekt zu erzeugen, das weitergeleitet werden soll. Ihre überschreibende Methode muss eine geeignete Methodensignatur für den angegebenen Selektor bereitstellen, indem Sie entweder eine Vorformulierung vornehmen oder ein anderes Objekt nach einem anderen Objekt fragen.

Und von der runtime Dokumentation:

... wenn ein Objekt alle Remote-Nachrichten leitet sie empfängt, sollte es eine Version von methodSignatureForSelector: haben, die genaue Beschreibungen der Methoden zurückgeben können, die letztlich reagieren zu den weitergeleiteten Nachrichten; zum Beispiel, wenn ein Objekt eine Nachricht an seinen Stellvertreter zu übermitteln in der Lage ist, würden Sie implementieren methodSignatureForSelector: wie folgt:

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

Hinweis: See Jilouc der answer für die ordnungsgemäße Durchführung der methodSignatureForSelector:.

+13

Ich denke, Apple's Runtime Programming Guide docs scheitern an diesem Problem. Im Abschnitt "Forwarding" erwähnen sie nichts über die Verwendung von 'methodSignatureForSelector:' mit 'forwardInvocation:'. Um diesen Leckerbissen zu finden, scrollen Sie in 3 Abschnitte, um herauszufinden, dass Sie eine Abschnittsmethode implementieren müssen. – DBD