2016-03-24 14 views
0

Ich habe eine Klasse, die Klassen für andere Klassen halten. Und diese Classes werden zur Laufzeit registriert, so dass ich den Class-Typ zur Kompilierzeit eigentlich nicht kenne. Aber später werde ich diese registrierten Klassen verwenden, um eine Instanz von ihnen zu erstellen. Hier ist meine KlassendefinitionErzeuge Instanz von Klasse Meta-Typ in Swift

Jetzt habe ich Mave Sammlung solcher Objekte, die die Typen halten.

let classTypesObj = registeredClassTypes() 
classTypesObj.setTypes(SomeClass.self, ParserContext: AnotherClass.self, ValidationContext: OneMoreClass.self) 

Und irgendwann werde ich Instanz von diesen Typen benötigen. Zwar ist es möglich, wie unten ist aber eine Schublade gesteckt zu-Klasse:

let requestType:SomeClass.Type = classTypesObj.URLContext as! SomeClass.Type 
let obj = requestType.init() //successfully creates the object of 'SomeClass' 

Ich habe einige Blogs genannt und kam dieses Objekt zu wissen, von Meta-Typ kann nicht ohne eine Schublade gesteckt erstellt werden.

Aber mein Problem ist, dass ich die Klasse 'SomeClass' nicht kennen werde, also kann ich es nicht auf 'SomeClass' tippen. Gibt es eine Möglichkeit, dies zu erreichen, um den Klassentyp dynamisch aufzulösen. Ich möchte so etwas wie diese oder andere Art und Weise:

let requestType = classTypesObj.URLContext 
let obj = requestType.init() 

Geworben this blog & this blog auch, aber sie sind typecasting es auch. Jede andere Möglichkeit, dieses Problem zu lösen, ist auch akzeptabel

Antwort

0

Diese Dynamik ist ein Kennzeichen von Ziel C, viel weniger in Swift. Swift bevorzugt statische Typisierung, alle Eigenschaften und Methoden sollten zur Kompilierzeit bekannt sein. Wenn Sie den aktuellen Ansatz beibehalten möchten, können Sie die dynamischen Teile in ObjectiveC schreiben und anschließend Erweiterungen in Swift erstellen.

Wenn Sie dies tun wollen rein Swift, betrachten Protokolle:

protocol URLContextProtocol { 
    init() 
    func method1() 
    func method2() 
} 

protocol ParserContextProtocol { 
    init() 
    func method3() 
    func method4() 
} 

protocol ValidationContextProtocol { 
    init() 
    func method5() 
    func method6() 
} 

func setTypes(URLContext: URLContextProtocol, ParserContext: ParserContextProtocol, ValidationContext: ValidationContextProtocol) { 
    // ... 
} 

Verbrauch:

class URLContext1: URLContextProtocol { ... } 
class URLContext2: URLContextProtocol { ... } 

let classTypesObj = RegisteredClassTypes() 
classTypesObj.setTypes(URLContext: URLContext1, ...) 

// Init an instance 
let obj = classTypeObj.URLContext() 
+0

Vielen Dank für Ihre Antwort. Wie diese Implementierung funktioniert, wenn ich viele Klassen habe, die mit jedem Protokoll übereinstimmen. Zum Beispiel kann ich 4-5 Klassen haben, die bestätigen, dass URLContextProtocol verschiedenen Zwecken dient. Und wie werde ich erfahren, welche Klasseninstanz aufgerufen werden soll, da Sie das Protokoll nur an die setTypes-Methode übergeben? – ImViresh

+0

Sie rufen 'init' auf dem Protokoll, nicht die Klasse. Ein Protokoll ist ein Versprechen, dass Ihre Klasse bestimmte Eigenschaften und Methoden implementiert. Es beschränkt nicht, wie diese Eigenschaften oder Methoden implementiert werden. Siehe meine bearbeitete Antwort –

Verwandte Themen