Wie kann man in Swift Language reflektieren ?
Wie kann ich eine Klasse instanziieren?
[[NSClassFromString(@"Foo") alloc] init];
ios
objective-c
swift
Selvin
quelle
quelle
Antworten:
Weniger hackige Lösung hier: https://stackoverflow.com/a/32265287/308315
Beachten Sie, dass Swift-Klassen jetzt einen Namespace haben. Anstelle von "MyViewController" wäre dies "AppName.MyViewController".
Dank der Antwort von Edwin Vermeer konnte ich etwas bauen, um Swift-Klassen in eine Obj-C-Klasse zu instanziieren:
BEARBEITEN
Sie können es auch in reinem obj-c tun:
Ich hoffe das hilft jemandem!
quelle
Sie müssen
@objc(SwiftClassName)
über Ihre schnelle Klasse setzen.Mögen:
quelle
NSClassFromString()
Die Funktion benötigt einen Namen, der durch die@objc
Zuordnung angegeben wird.@objc(SubClass)
funktioniert, aber@objc class SubClass
nicht?@objc class SubClass
Form wird impliziert, dass der Name mit dem Namen der Unterklasse identisch ist. Und in der@objc(SubClass) class SubClass
Form ist es direkt angegeben. Ich denke, der Compiler kann es aus irgendeinem Grund in der ersten Form einfach nicht selbst herausfinden.Auf diese Weise habe ich UIViewController nach Klassennamen abgeleitet
Weitere Informationen finden Sie hier
In iOS 9
quelle
UPDATE: Ab Beta 6 gibt NSStringFromClass Ihren Bundle-Namen plus den durch einen Punkt getrennten Klassennamen zurück. Es wird also so etwas wie MyApp.MyClass sein
Swift-Klassen haben einen konstruierten internen Namen, der aus den folgenden Teilen besteht:
Ihr Klassenname lautet also ungefähr _TtC5MyApp7MyClass
Sie können diesen Namen als Zeichenfolge erhalten, indem Sie Folgendes ausführen:
Update In Swift 3 wurde Folgendes geändert:
Mit dieser Zeichenfolge können Sie eine Instanz Ihrer Swift-Klasse erstellen, indem Sie Folgendes ausführen:
quelle
Es ist fast das gleiche
Überprüfen Sie dieses Dokument:
https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/#//apple_ref/c/func/NSClassFromString
quelle
NSClass
Klassen, nicht mit Swift-Klassen.NSClassFromString("String")
kehrt zurücknil
,NSClassFromString("NSString")
tut es aber nicht.var myVar:NSClassFromString("myClassName")
String
ist keine Klasse; Es ist eine StrukturNSClassFromString
kehrt auchnil
für alle Swift-Klassen zurück.Ich konnte ein Objekt dynamisch instanziieren
Ich habe keinen Weg gefunden,
AnyClass
aus einem zu erstellenString
(ohne Obj-C zu verwenden). Ich denke, sie wollen nicht, dass Sie das tun, weil es im Grunde das Typensystem bricht.quelle
Für swift2 habe ich eine sehr einfache Erweiterung erstellt, um dies schneller zu tun. Https://github.com/damienromito/NSObject-FromClassName
In meinem Fall mache ich das, um den gewünschten ViewController zu laden:
quelle
Dadurch erhalten Sie den Namen der Klasse, die Sie instanziieren möchten. Dann können Sie Edwins Antwort verwenden , um ein neues Objekt Ihrer Klasse zu instanziieren.
Ab Beta 6
_stdlib_getTypeName
wird der verstümmelte Typname einer Variablen abgerufen. Fügen Sie dies in einen leeren Spielplatz ein:Die Ausgabe ist:
Der Blogeintrag von Ewan Swick hilft beim Entschlüsseln dieser Zeichenfolgen: http://www.eswick.com/2014/06/inside-swift/
zB
_TtSi
steht für Swifts internenInt
Typ.quelle
In Swift 2.0 (getestet im Xcode 7.01) _20150930
quelle
xcode 7 beta 5:
quelle
Zeichenfolge aus der Klasse
oder
Initiieren Sie eine UIViewController-Klasse aus einer Zeichenfolge:
quelle
Ich benutze diese Kategorie für Swift 3:
Die Verwendung wäre:
quelle
Ich glaube, ich habe Recht, wenn ich sage, dass Sie das nicht können, zumindest nicht mit der aktuellen Beta (2). Hoffentlich wird sich dies in zukünftigen Versionen ändern.
Sie können
NSClassFromString
eine Variable vom TypAnyClass
abrufen, aber in Swift scheint es keine Möglichkeit zu geben, sie zu instanziieren. Sie können eine Brücke zu Ziel C verwenden und dort ausführen oder - falls dies in Ihrem Fall funktioniert - auf die Verwendung einer switch-Anweisung zurückgreifen .quelle
Anscheinend ist es (nicht mehr) möglich, ein Objekt in Swift zu instanziieren, wenn der Name der Klasse nur zur Laufzeit bekannt ist. Ein Objective-C-Wrapper ist für Unterklassen von NSObject möglich.
Zumindest können Sie ein Objekt derselben Klasse wie ein anderes zur Laufzeit angegebenes Objekt ohne einen Objective-C-Wrapper instanziieren (mit xCode Version 6.2 - 6C107a):
quelle
In Swift 2.0 (getestet in der Beta2 von Xcode 7) funktioniert es folgendermaßen:
Natürlich muss der Typ, von
NSClassFromString
dem er kommt, dieses Init-Protokoll implementieren.Ich gehe davon aus, dass es klar ist, dass es sich um
className
einen String handelt, der den Obj-C-Laufzeitnamen der Klasse enthält, der standardmäßig NICHT nur "Foo" ist, aber diese Diskussion ist meiner Meinung nach nicht das Hauptthema Ihrer Frage.Sie benötigen dieses Protokoll, da standardmäßig alle Swift-Klassen keine
init
Methode implementieren .quelle
Sieht aus wie die richtige Beschwörung wäre ...
... wobei "p" für "verpackt" steht - ein besonderes Problem.
Die kritische Umwandlung von AnyClass in T führt derzeit jedoch zu einem Absturz des Compilers. In der Zwischenzeit muss die Initialisierung von k in einen separaten Abschluss verschoben werden, der sich gut kompilieren lässt.
quelle
Ich benutze verschiedene Ziele, und in diesem Fall wird die schnelle Klasse nicht gefunden. Sie sollten CFBundleName durch CFBundleExecutable ersetzen. Ich habe auch die Warnungen behoben:
quelle
Ist die Lösung nicht so einfach?
quelle
Auch in Swift 2.0 (möglicherweise vorher?) Können Sie direkt mit der
dynamicType
Eigenschaft auf den Typ zugreifendh
Ausgabe
Funktioniert für meinen Anwendungsfall
quelle
Versuche dies.
quelle
Ich habe so implementiert,
quelle
Swift 5 , einfach zu bedienen, dank @Ondrej Rafaj's
Quellcode:
Rufen Sie so an:
quelle
Ein hier gezeigtes Beispiel für einen Seitensprung, die Hoffnung kann Ihnen helfen!
quelle
Swift3 +
quelle
Hier ist ein gutes Beispiel:
quelle