Blog

Schnelle optionale Verkettung und Auswertung von Methodenargumenten

Lammert Westerhoff

Lammert Westerhoff

Aktualisiert Oktober 22, 2025
3 Minuten
Jeder, der schon einmal in Swift programmiert hat, weiß, dass Sie eine Methode für ein optionales Objekt mit einem Fragezeichen (?) aufrufen können. Dies wird optionale Verkettung genannt. Aber was ist, wenn diese Methode Argumente annimmt, deren Wert Sie von derselben Option erhalten müssen? Können Sie das Auspacken dieser Werte sicher erzwingen? Ein häufiger Anwendungsfall ist ein UIViewController, der nach einer gewissen Verzögerung oder nach einem Netzwerkaufruf Code innerhalb einer Closure ausführt. Wir möchten eine schwache Referenz auf self innerhalb dieser Closure behalten, weil wir sicher sein wollen, dass wir keine Referenzzyklen erzeugen, falls die Closure beibehalten wird. Außerdem brauchen wir (normalerweise) dieses Stück Code innerhalb der Closure nicht auszuführen, falls der View Controller vor der Ausführung der Closure beendet wurde. Hier ein vereinfachtes Beispiel: [objc] class ViewController: UIViewController { let finishedMessage = "Netzwerkaufruf wurde beendet" let messageLabel = UILabel() override func viewDidLoad() { super.viewDidLoad() someNetworkCall { [weak self] in self?.finished(self?.finishedMessage) } } func finished(message: String) { messageLabel.text = message } } [/objc] Hier rufen wir die Funktion someNetworkCall auf, die einen () -> () Abschluss als Argument erhält. Sobald der Netzwerkaufruf beendet ist, ruft er diese Closure auf. Innerhalb der Schließung möchten wir den Text unserer Beschriftung in eine Fertigmeldung ändern. Leider lässt sich der obige Code nicht kompilieren. Das liegt daran, dass die Methode finished einen nicht-optionalen String als Parameter nimmt und keinen optionalen, der von self?.finishedMessage zurückgegeben wird. Ich habe dieses Problem gelöst, indem ich den Code in eine if let-Anweisung verpackt habe: [objc] if let this = self { this.finished(this.finishedMessage) } [/objc] Das funktioniert ganz gut, vor allem, wenn es mehrere Codezeilen gibt, die übersprungen werden sollen, wenn self zu Null wird (z.B. wenn der View-Controller beendet und deallociert wurde). Aber ich habe mich immer gefragt, ob es sicher ist, die Methodenargumente auch dann zu entpacken, wenn self null ist: [objc] self?.finished(self!.finishedMessage) [/objc] Die Frage hier ist: wertet Swift das Argument einer Methode auch dann aus, wenn die Methode nicht aufgerufen wird? Ich habe das Swift Programmierhandbuch nach Informationen zu diesem Thema durchsucht, konnte aber keine Antwort finden. Zum Glück ist es nicht schwer, das herauszufinden. Fügen wir eine Methode hinzu, die finishedMessage zurückgibt und eine Nachricht ausgibt, und rufen dann die finished-Methode für ein Objekt auf, von dem wir sicher wissen, dass es null ist. [objc] override func viewDidLoad() { super.viewDidLoad() let vc: ViewController? = nil vc?.finished(printAndGetFinishedMessage()) } func printAndGetFinishedMessage() -> String { println("Getting message") return finishedMessage } [/objc] Wenn wir dies ausführen, sehen wir, dass nichts auf der Konsole ausgegeben wird. Jetzt wissen wir also, dass Swift die Methodenargumente nicht auswertet, wenn die Methode nicht aufgerufen wird. Daher können wir unseren ursprünglichen Code in den folgenden ändern: [objc] someNetworkCall { [weak self] in self?.finished(self!.finishedMessage) } [/objc]

Verfasst von

Lammert Westerhoff

Contact

Let’s discuss how we can support your journey.