Ich versuche, class
mithilfe von Generika dynamisch einen instanzbasierten Typ zu erstellen , habe jedoch Schwierigkeiten mit der Klassenintrospektion.
Hier sind die Fragen:
- Gibt es ein Swift-Äquivalent zu Obj-C
self.class
? - Gibt es eine Möglichkeit, eine Klasse anhand des
AnyClass
Ergebnisses von zu instanziierenNSClassFromString
? - Gibt es eine Möglichkeit,
AnyClass
Informationen ausschließlich aus einem generischen Parameter abzurufen oder auf andere Weise einzugebenT
? (Ähnlich der C #typeof(T)
-Syntax)
introspection
swift
Erik
quelle
quelle
self.class
würdenself.dynamicType.self
in Swift I Glauben werdenself.dynamicType.foo()
Antworten:
Nun, zum einen, die Swift Äquivalent
[NSString class]
heißt.self
(siehe Metatyp docs , obwohl sie ziemlich dünn sind).In der Tat
NSString.class
funktioniert nicht einmal! Du musst benutzenNSString.self
.Ebenso habe ich mit einer schnellen Klasse versucht ...
Hmm ... der Fehler sagt:
Ich habe eine Weile gebraucht, um herauszufinden, was das bedeutet. Es stellt sich heraus, dass die Klasse eine haben soll
@required init()
Einige der Dokumente beziehen sich darauf
.Type
,MyClass.Type
geben mir aber einen Fehler auf dem Spielplatz.quelle
.Type
oder.Protocol
in Variablendeklaration verwenden, zBlet myObject: MyObject.Type = MyObject.self
@
vorherrequired
sollte gelöscht werdenHier erfahren Sie, wie Sie es verwenden
NSClassFromString
. Sie müssen die Oberklasse dessen kennen, womit Sie enden werden. Hier ist ein Paar aus Oberklasse und Unterklasse, das sich selbst beschreiben kannprintln
:Beachten Sie die Verwendung der speziellen
@obj
Syntax, um den Objective-C-Munged-Namen dieser Klassen zu bestimmen. Das ist entscheidend, weil wir sonst die Munged-Zeichenfolge, die jede Klasse kennzeichnet, nicht kennen.Jetzt können wir
NSClassFromString
die Zork-Klasse oder die Zilk-Klasse erstellen, da wir wissen, dass wir sie als NSObject eingeben und später nicht abstürzen können:Und es ist reversibel;
println(NSStringFromClass(anObject.dynamicType))
funktioniert auch.Moderne Version:
quelle
@objc(ClassName)
bisschen. Ich wusste über das@objc
Attribut Bescheid , aber nicht, dass Sie auch einen Hinweis auf den Klassennamen geben könnten.as! NSObject.Type
in der ersten Zeile undaClass.init()
in der zweitenWenn ich die Dokumentation richtig lese, wenn Sie sich mit Instanzen befassen und z. B. eine neue Instanz desselben Typs als das Objekt zurückgeben möchten, das Sie erhalten haben, und der Typ mit einem init () erstellt werden kann, können Sie Folgendes tun:
Ich habe es schnell mit String getestet:
das hat gut funktioniert.
quelle
dynamicType
funktioniert wie ich dort erwartet hatte. Ich konnte jedoch keine Typen vergleichen. Der wirklich große Nutzen liegt bei Generika, also könnte ich so etwas wieGeneric<T>
und drinnen habenif T is Double {...}
. Es scheint, dass dies nicht unglücklicherweise möglich ist.Defaultable
Protokoll erstellen , das ähnlich wie dasdefault
Schlüsselwort von C # funktioniert , und geeignete Erweiterungen für Typen wieString
undInt
. Durch Hinzufügen der generischen Einschränkung vonT:Defaultable
konnte ich überprüfen, ob das Argument übergeben wurdeis T.default()
.value is String.default()
... etc tun musst, was duvalue is String
stattdessen einfach tun würdest .In schneller 3
ist veraltet.
Verwenden Sie stattdessen:
quelle
Schnelle Implementierung von Vergleichstypen
HINWEIS: Beachten Sie, dass es auch mit Protokollen funktioniert, die das Objekt möglicherweise erweitert oder nicht
quelle
Endlich etwas zum Arbeiten. Es ist ein bisschen faul, aber selbst die NSClassFromString () -Route hat bei mir nicht funktioniert ...
und Bingo, "makeFoo" enthält eine Foo-Instanz.
Der Nachteil ist, dass Ihre Klassen von FactoryObject abgeleitet sein müssen und die Obj-C + -Initialisierungsmethode haben MÜSSEN, damit Ihre Klasse von der globalen Funktion "mapClass" automatisch in die Klassenzuordnung eingefügt wird.
quelle
Hier ist ein weiteres Beispiel, das die Implementierung der Klassenhierarchie zeigt, ähnlich der akzeptierten Antwort, die für die erste Version von Swift aktualisiert wurde.
Druckt dieses Ergebnis:
quelle
var x: NamedItem.Type
Wenn ich es beispielsweise zuweisex = Folder.Type
, wirdx()
ein neues zurückgegebenNamedItem
, kein aFolder
. Dies macht die Technik für viele Anwendungen unbrauchbar. Ich halte das für einen Fehler .