2016-08-04 15 views
0

Ich versuche, einen universellen Fehlerhandler für meine Anwendung zu erstellen und die Sache noch komplizierter zu machen Ich verwende einen Ereignisbus, um eine Aufgabe zu übergeben, so dass ich den Typ nicht angeben kann Kompilierzeit. Ich versuche, die folgend zu tun:Schnelle Umwandlung ohne Angabe des generischen Typs

let apiTask = data.object as! Task // Option 1 
let apiTask = data.object as! Task<AnyObject> // Option 2 

apiTask!.continueWith { (task) in 
    if(task.cancelled || task.faulted) { 
     self.isInError = true 
    } else { 
     self.isInError = false 
    } 
} 

Option 1 gibt eine Kompilierung Fehlermeldung, dass den generischen Typ TResut die Aufgabe kann nicht geschlossen werden. Option 2 verursacht eine Fehlerlaufzeit Task<SpecificType> cannot be caster to Task<AnyObject>

Ich habe die gleiche Implementierung in Java zu sagen, wo es Sie nicht scheint, dass es den generischen Typ angeben. Task<TResult> könnte potenziell jeder Typ sein, so dass ich es in der obigen Methode nicht angeben kann. Gibt es eine Möglichkeit, dies zu umgehen?

Antwort

1

Es klingt, als ob Sie eigentlich keinen generischen Typ wollen. Es gibt generische Typen, die zur Kompilierungszeit genau die Art von Typinformationen angeben, die Sie löschen möchten. Wenn Sie den generischen Parameter fast immer ignorieren möchten, sollten Sie einen nicht-generischen Typ angeben. Wenn jedoch in der Regel Sie diese Informationen verwenden, können Sie es in bestimmten Methoden ignorieren: Sie werden nur jene Methoden generic sowieso machen müssen:

func doSomething<T>(to: Task<T>) { 
    //Do whatever you want that doesn't involve `T`. 
    //You still have to make this method generic so it accepts any type of `Task`. 
} 
+0

Leider kann ich das nicht tun, da die 'Task' in' data.object' gespeichert ist. Jetzt ist das nicht wirklich sicher, aber ich bin bereit, das Risiko einzugehen und zu versuchen, dies zu einer "Aufgabe" zu machen. Leider scheint Swift das nicht zuzulassen –

+1

Also Option 1 (Wechsel zu einem nicht-generischen Typ) ist out. Option 2 ist es! Machen Sie Ihre universellen Error-Handler-Methoden selbst generisch, wie oben gezeigt. – andyvn22

0

Haben Sie darüber nachgedacht, machen Aufgabe ein Protokoll (oder ein konform Protokoll)?

protocol Task { 
    func execute() 
} 

class SimpleTask<T>: Task { 
    let parameter: T 
    init(parameter: T) { 
     self.parameter = parameter 
    } 
    func execute() { 
     print("executing task with parameter: \(parameter)") 
    } 
} 

func executeTask(task: Task) { 
    task.execute() 
} 

let simpleTask = SimpleTask<Int>(parameter: 1) 
executeTask(simpleTask) 
0

sah ich Ihren Beitrag auf dem Bolzen-Swift issue tracker und da ich weiß nicht, ob Sie meine Antwort dort sehe ich dachte, dass ich es auch hier posten. Ich bin neu zu Bolts und auch ein Anfänger in Swift, aber ich habe ein paar Jahre Erfahrung als Programmierer, so ist dies eine mögliche Lösung, die ich mit kam:

Ich denke, Sie könnten eine Klasse oder Struktur erstellen, die als a fungiert Wrapper zu Ihrem tatsächlichen Ergebnis. Diese Struktur/Klasse benötigt nur eine Variable vom Typ AnyObject. Sie verwenden dies dann als generischen Typ Ihrer Aufgaben. Später können Sie den Typ des Ergebnisses überprüfen. E. G. unter Verwendung von if let string = task.result?.result as? String{...}. Sehen Sie den Code unten, um zu verstehen, was ich meine.

Wie gesagt, ich bin ein Anfänger in Bolts and Swift und wahrscheinlich gibt es eine bessere Lösung. Wenn Sie bereits eine bessere Lösung gefunden haben, können Sie sie vielleicht hier veröffentlichen und als Antwort auf Ihre Frage auswählen. :)

Verwandte Themen