Frage

Der folgende Code implementiert eine NSProxy Unterklasse, die Methoden zu einer NSNumber Instanz weiterleitet.

Doch beim Aufruf [nsproxy floatvalue] Ich erhalte 0.0 unter GCC 4.2.

Unter LLVM-Clang erhalte ich die richtige Antwort 42.0.

Jede Idee, was ist hier los?

(übrigens diese unter Garbage Collection ausgeführt wird)

-(id) init;
{
    _result = [NSNumber numberWithFloat:42.0];
    return self;
}

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

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    [anInvocation setTarget:_result];
    [anInvocation invoke];
    return;
} 
War es hilfreich?

Lösung

Ihre Proxy-Klasse deklariert die Nachricht nicht Signatur für -floatValue. Da es eine Fließkommazahl zurückgibt, kann das ein Problem sein. Weil Sie nicht erklärt haben, an jeden Ort und vermutlich es wirft nicht Ihr Proxy-Objekt in seine dargestellt Klasse hat der Compiler bei der Methodensignatur zu erraten. In diesem Fall schätzt die GCC-Compiler, dass die Nachricht einen id Zeiger zurück.

In Objective-C, abhängig von der Signatur der Nachricht und der Architektur der Maschine erhalten verschiedene Funktionen für die Verarbeitung der Nachricht und ihre Rückgabewerte verwendet. Auf x86-Rechner Nachrichten, die einen Fließkommawert zurückgeben, werden durch objc_msgSend_fpret während Funktionen aufgerufen, die void und id Verwendung objc_msgSend zurück.

Da die GCC-Compiler davon aus, dass der Rückgabewert ist ein id es die letztere Funktion verwendet und verarbeitet falsch das Ergebnis. Das Clang der Lage ist, diese richtig zu handhaben ist interessant, aber ich würde auf diesem Verhalten verlassen zögern. Es wäre besser, eine Kategorie auf Ihrem Proxy für alle Methoden zu erklären, dass Sie die Weiterleitung sein werden. Das hat auch den Vorteil, die Warnung zu entfernen, die für die Codezeile erzeugt wurde die floatValue Methode aufrufen.

@interface Foo (ProxyMethods)
- (float)floatValue;
@end

Andere Tipps

Jede init Methode sollte [super init]; rufen unerwartetes Verhalten zu verhindern. Wie so:

- (id)init {
    self = [super init];
    if (self) {
        // Your init code
    }
    return self;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top