2016-12-29 2 views
1

Das Erstellen von Klasseninstanzen in Java aus String ist nicht schwierig, aber ich bin neu in swift und mache dasselbe in dieser Sprache sehr schwierig für mich.Reflection von Java zu Swift

MOTIVATION:

Ich brauche unbekannte Controller und seine unbekannten Methoden aufrufen (MVC)

Java

String className = "MyClass"; 
String methodName = "MyMethod"; // with one argument like (String[] args) and return String 

// in swift can be a Dictionary 
String[] argument = new String[] {"A", "B"} 

Class<?> clazz = Class.forName(className); 
Object instance = clazz.newInstance(); 

Method method = clazz.getDeclaredMethod(methodName, Class<?>[]); 

Object returnStringObject = method.invoke(instance, argument); 

Mein Versuch in Swift

let clazz: AnyClass? = NSClassFromString(className) 

if clazz != nil { 
    // ERRORRRRRR (use of unresolved identifier NSSelectorFromString) 
    let selector: Selector = NSSelectorFromString(methodName) 

    // ERRORRRRRR (cannot invoke performeSelector with an argument list of type selector) 
    clazz?.performSelector(selector) 
} 

Wie kann ich tun, um die gleiche Sache von Java zu schnellen

+0

Die Auswahllinie sollte eigentlich keinen Fehler verursachen. ABER der zweite Fehler ist gerechtfertigt, da Sie derzeit nur die Klassenreferenz und keine Instanz haben. Was du jetzt vermisst, ist das Äquivalent zu "clazz.newInstance()". – luk2302

+0

@ luk2302 Können Sie ein Beispiel veröffentlichen? leider gibt es keine solchen beispiele für swift wie das was ich in java gepostet habe. – Mystic

+0

sind alle Klassen, die in der Unterklasse von NSObject übergeben werden können? – luk2302

Antwort

2

Die folgenden für Sie arbeiten:

let cla = NSClassFromString(className) 
if let cla = cla as? NSObject.Type { 
    let selector: Selector = NSSelectorFromString(methodName) 
    let instance = cla.init() 
    if (instance.responds(to: selector)) { 
     print(instance.perform(selector)) 
    } else { 
     print("method not found") 
    } 
} else { 
    print("class not found") 
} 

Beachten Sie, dass es wahrscheinlich die Dinge wäre viel einfacher und gibt sicherer einfach eine Karte haben/Wörterbuch von [String:ControllerInstances], aus dem Sie Ihren Zielcontroller auswählen können. Auf diese Weise können Ihre Controller komplexere Initialisierer haben und Sie haben jeweils eine verwaltete Instanz, die nicht immer wieder neu erstellt wird.

+0

Vielen Dank! – Mystic