Frage

Ich kam in einem seltsamen Problem heute. Ich habe eine Unterklasse von UIView und hinzugefügt nur 1 Verfahren auf den von Xcode bereitgestellt Template-Code.

@interface FloatView : UIView {

}
- (void)floatTest:(CGFloat)x;
@end

- (void)floatTest:(CGFloat)x {
  NSLog(@"float was %f", x);
}

Da ist in meinem AppDelegate hatte ich Code wie folgt:

UIView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];

Ganz einfach, nicht wahr? Was soll diese ausdrucken? Ich dachte, es wäre so etwas wie „10.0000“, aber nein, es ausdruckt „0.000000“.

ich mit dieser rang stundenlang versucht, herauszufinden, was ich tat, falsch, und dann änderte ich den Code in meinem AppDelegate zu

FloatView *floatView = [[FloatView alloc] init];
[floatView floatTest:10.0f];

Erst dann hat es die erwarteten „10.0000“ ausdrucken. Warum ist das so? Ich habe FloatView als Unterklasse von UIView erklärt, soll ich nicht in der Lage ein FloatView Objekt zu einem UIView Zeiger ohne Probleme zuweisen?

Auch wenn floatView einen Zeiger auf eine UIView erklärt wurde, ist es wirklich ein floatView und es sollte die floatTest Nachricht verarbeiten können? Bin ich total weg Basis hier?

War es hilfreich?

Lösung

Eigentlich Polymorphismus funktioniert wie erwartet. Wenn es nicht funktioniert, würde nichts gedruckt wurde (in Ihrem Beispiel 0,0000 gedruckt wird). Die Sache ist, während die Instanz tatsächlich reagiert Nachricht an testFloat:10.0f, da der Compiler nicht statisch die Methodendeklaration sehen kann (als UIView Klasse nicht, ein solches Verfahren nicht erklären), geht davon aus, dass Ihre Methode als Argument und gibt ... id nimmt.

Wenn CGFloat an eine Methode übergeben wird, die variable Anzahl von Argumenten (...) erwartet, wird es gefördert double. Somit wird das Empfangsverfahren ein double Argument übergeben und denkt, dass es ein float ist und es nicht richtig gedruckt bekommt.

Sie können dieses Verhalten überprüfen, indem NSLog Linie auf sich ändernde:

NSLog(@"%f", *(double*)&x);

Wenn der Compiler die Nachricht sendet eher FloatView* als ein UIView*, kann er die genaue Signatur der Methode finden. Es kann es wirklich sehen CGFloat erwartet und fördert nicht das Argument double. Als Ergebnis funktioniert es einwandfrei.

Außerdem, wenn UIView* die Methode Erklärung enthalten, die eine CGFloat nahm, würde der Compiler die Methode in geeigneter Weise nennen. Um es zusammenzufassen, ist dies nicht ein Polymorphismus Problem ist; es ist eine fehlende Signatur der Methode Ausgabe.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top