Closures in Swift sind eigenständige Codeblöcke, die Verweise auf Variablen und Konstanten aus dem umgebenden Kontext erfassen und speichern können. Sie ermöglichen die Organisation von Callbacks, die asynchrone Verarbeitung und das Speichern der Codeausführung als Werte von Variablen.
var counter = 0 let incrementer: () -> Void = { counter += 1 } incrementer() print(counter) // 1
[weak self], [unowned self]) definiert werden.self innerhalb eines Closures erfasst wird.Was ist der Unterschied zwischen einer strong-Capture und der Verwendung von
[weak self]oder[unowned self]in der Capture-Liste eines Closures? Welche Konsequenzen hat das?
Antwort:
Wenn Sie [weak self] oder [unowned self] nicht angeben, erfasst das Closure standardmäßig self durch eine starke Referenz, was zu einem Retain-Cycle führt, wenn das Closure und self aufeinander verweisen. [weak self] erfasst self durch eine schwache Referenz (optional), [unowned self] durch eine unkontrollierte Referenz (non-optional). Eine falsche Wahl oder das Fehlen der Capture-Liste führt zu Speicherlecks oder Abstürzen.
class Test { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doWork() } } func doWork() { ... } }
Geschichte
Ein Programmierer verwendete keine Capture-Liste in einem Closure innerhalb eines UIViewControllers, der asynchrone Datenladevorgänge startete. Infolgedessen wurden der Controller und seine Ansicht nicht freigegeben, was zu einem Speicherleck nach dem Schließen (Dismiss) führte. Eine Analyse der Infrastruktur ergab Hunderte von "hängenden" Controllern im Speicher.
Geschichte
Das Closure erfasste self mit [unowned self], der Lebenszyklus von self endete jedoch vor dem Closure. Dies führte zu einem Absturz beim Zugriff auf das bereits freigegebene Objekt — die Anwendung stürzte ab, als sie versuchte, innerhalb des Closures mit self zu arbeiten.
Geschichte
In einem Projekt erfassten in einem verschachtelten Closure zwei Variablen: eine stark, die andere schwach. Es stellte sich heraus, dass der weak-Verweis zu früh null wurde und die für die Arbeit des Closures erforderlichen Daten verloren gingen — der Bug trat nur im Stress-Test unter Last in einer mehrwertigen Umgebung auf.