Frage

Ich bin mit einem Rahmen, und Verwendungen ‚ClassA‘ definiert, eine Unterklasse von NSObject. Ich möchte einige Variablen und Funktionen hinzuzufügen, so natürlich habe ich ‚ClassB‘, eine Unterklasse von ‚KlasseA‘

Nun mein Problem ist folgendes. Viele der Verfahren in diesem Rahmen zurückzukehren Instanzen von ‚KlasseA‘, die Ich mag würde meine Unterklasse werfen.

Zum Beispiel dieser Methode nehmen:

- (ClassA *)doSomethingCool:(int)howCool

Jetzt in meinem Code ich versuche dies:

ClassB * objB;
objB = (ClassB *)doSomethingCool(10); 

NSLog(@"objB className = %@", [objB className]);

Das läuft ganz gut. Keine Kompilierung oder Laufzeitfehler oder sonst etwas. Aber was ist wirklich seltsam für mich ist die Ausgabe:

>> "objB className = ClassA"

Das Casting offensichtlich fehlgeschlagen. Nicht sicher, was an dieser Stelle passiert ist ... objB wird eingegeben als ‚ClassB‘, aber es ist classname ‚KlasseA‘ ist und es wird nicht zu einem ‚ClassB‘ Methoden reagieren.

Nicht sicher, wie dies möglich ist ... Wer weiß, was ich hier falsch mache?

fand ich eine ähnliche Position, die von genau das Gegenteil, was ich frage hier

War es hilfreich?

Lösung

Casting Objektvariablen in Objective-C ist in der Regel ein Fehler (es gibt ein paar Fälle, in denen es richtig ist, aber nie für diese Art der Sache). Beachten Sie, dass Sie nicht ein Objekt Gießen - Sie wirft einen Zeiger auf ein Objekt. Sie haben dann einen Zeiger vom Typ ClassB*, aber es immer noch auf derselben Instanz von KlasseA. Die Sache deutete auf hat überhaupt nicht verändert.

Wenn Sie wirklich Instanzen KlasseA zu ClassB konvertieren möchten, müssen Sie eine ClassB Konstruktor schreiben, die eine ClassB Instanz von einem KlasseA erstellen können. Wenn Sie wirklich Instanzvariablen hinzufügen müssen, könnte dies die beste Wahl sein.

Wie Jason sagte, aber es ist oft eine gute Idee, zunächst eine Kategorie zu versuchen.

Andere Tipps

Sie können nicht nur eine Superklasse zu seiner Unterklasse werfen. Es ist nicht wirklich alle Ihre hinzugefügt Variablen / Eigenschaften oder Methoden implementieren. Sobald Sie es mit einem Verfahren zur Meldung versuchen Sie auf Ihre Unterklasse definieren, werden Sie eine Laufzeitausnahme und Ihre Anwendung zu erhalten, ist aufhören würde. Sie können nur sicher in eine Richtung geworfen: aus spezielleren auf allgemeinere. Das heißt, Sie unseren ClassB zu einem KlasseA sicher werfen können, nur die Methoden und Eigenschaften der Klasse A verwendet wird, aber in der anderen Richtung nicht um.

Denken auf diese Weise davon: Sie ein Auto haben (die Elternklasse) und eine FourDoorSedan (die Unterklasse). Jedes Auto hat einen Motor und zwei Türen. Nun lassen Sie uns sagen, dass Sie von irgendwo ein Auto bekommen, und das ist wirklich alles, was Sie darüber wissen. Sie sagen dem Betreiber, das Auto ein FourDoorSedan ist, aber in der Tat stellt sich heraus, es ist nicht. Also, wenn der Bediener so etwas wie tut: openBackPassengerDoor, was passiert? Es gibt nur zwei Türen !! Es ist das gleiche hier.

Wenn Sie nur ein wenig Funktionalität KlasseA hinzufügen möchten Besuche Objective-C Kategorien, sind sie wahrscheinlich das, was Sie wollen und kein Casting erforderlich. Lesen Sie die Dokumentation sorgfältig, aber, weil sie nicht ohne ihre Einsprüche sind.

Wenn Sie nur eine Methode, um vorhandene Objekte hinzufügen möchten, ist Subklassifizieren nicht der richtige Weg. Sie können Verfahren zu bestehenden Klassen (und die Instanzen) mit Hilfe eines Sprachfeatures Kategorie .

Beispiel:

//"ClassA+doSomethingCool.h"
@interface ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool;
@end


//"ClassA+doSomethingCool.m"
@implementation ClassA (doSomethingCool)
- (ClassA *)doSomethingCool:(int)howCool
{

}
@end

Casting konvertiert nicht von einer Art von Objekt zu einem anderen. Sie können nicht eine Bibliothek zwingen Art des Objekts zu ändern und eine andere Art von Objekten zu erstellen, es sei denn es einige Fabrikmuster verwendet wird.

Was passiert, wenn Sie einen Ihrer Unterklasse Methoden auf dem Objekt zurückrufen?

ClassB * objB;
objB = (ClassB *)doSomethingCool(10);
[objB subClassMethod];

Obj-C ziemlich frei und verliert mit Typen, Sie brauchen nicht einmal die Art vor der Hand zu wissen, zum Beispiel. Sie könnten alle Ihre ClassB Verweise auf id ändern. Ich weiß, es ist sicherer zu wissen, dass Sie die erwarteten Typ, aber wenn der Code korrekt ist, sollte es keine Rolle.

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