Capture-Listen und Weak Self
Vermeiden Sie Retain Cycles mit [weak self].
Capture-Listen und Weak Self ist eine kostenlose Swift Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Swift Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.
Das Risiko eines Retain-Zyklus
Wenn ein Objekt eine escapende Closure speichert, die self stark erfasst, halten beide einander dauerhaft am Leben — ein Retain-Zyklus, der ein Speicherleck verursacht.
Ein starker Zyklus
Die Closure erfasst self stark, und self hält die Closure — keines von beiden wird jemals freigegeben:
class Owner {
var onEvent: (() -> Void)?
func setup() {
onEvent = { print(self.describe()) } // strong self -> cycle
}
func describe() -> String { "Owner" }
}
let o = Owner(); o.setup()
o.onEvent?() // "Owner" (but leaks)Capture-Listen
Eine Capture-Liste am Anfang einer Closure { [weak self] in ... } steuert, wie jede erfasste Referenz gehalten wird: mit weak oder unowned statt stark.
Den Zyklus mit weak self durchbrechen
[weak self] erfasst self als Optional, wodurch es nicht am Leben gehalten wird:
class Owner {
var onEvent: (() -> Void)?
func setup() {
onEvent = { [weak self] in
print(self?.describe() ?? "gone")
}
}
func describe() -> String { "Owner" }
}
let o = Owner(); o.setup()
o.onEvent?() // "Owner" (no cycle)weak macht self optional
Mit [weak self] wird self zu Self?, daher müssen Sie es entpacken:
class Worker {
var tag = "W"
lazy var job: () -> Void = { [weak self] in
guard let self = self else { return }
print(self.tag)
}
}
let w = Worker()
w.job() // "W"Das guard-let-self-Muster
Binden Sie self frühzeitig neu, damit der restliche Closure-Code eine starke, nicht optionale Referenz verwendet:
class Service {
var name = "S"
lazy var run: () -> Void = { [weak self] in
guard let self else { return }
print(self.name)
print("still \(self.name)")
}
}
Service().run() // "S" / "still S"weak vs. unowned
weak liefert ein Optional und ist sicher, wenn das Objekt bereits verschwunden sein kann. unowned ist nicht optional und schneller, führt aber zum Absturz, wenn nach der Freigabe des Objekts darauf zugegriffen wird — verwenden Sie es nur, wenn garantiert ist, dass self länger als die Closure lebt.
unowned verwenden
Wählen Sie unowned, wenn die Closure nicht länger als self leben kann:
class Timer2 {
var ticks = 0
lazy var tick: () -> Void = { [unowned self] in
self.ticks += 1
}
}
let t = Timer2()
t.tick(); t.tick()
print(t.ticks) // 2Bestimmte Eigenschaften erfassen
Erfassen Sie nur, was Sie benötigen, statt self vollständig zu erfassen — manchmal vermeiden Sie den Zyklus dadurch vollständig:
class VM {
let id = 42
lazy var printer: () -> Void = { [id] in print(id) }
}
VM().printer() // 42Non-Escaping benötigt kein weak
Synchrone, non-escaping Closures (wie map) verursachen keine Zyklen. Daher ist es dort unproblematisch, self stark zu erfassen:
class Calc {
let factor = 3
func scale(_ xs: [Int]) -> [Int] {
xs.map { $0 * self.factor } // safe, non-escaping
}
}
print(Calc().scale([1, 2])) // [3, 6]Faustregel
Verwenden Sie [weak self] für gespeicherte oder escapende Closures, die auf self verweisen. Verwenden Sie unowned nur, wenn garantiert ist, dass self am Leben bleibt. Verzichten Sie bei non-escaping Closures auf Capture-Listen.
class P {
var n = "P"
var stored: (() -> Void)?
func arm() { stored = { [weak self] in print(self?.n ?? "-") } }
}
let p = P(); p.arm(); p.stored?() // "P"Kurze Überprüfung
Warum verwendet man [weak self] in einer gespeicherten escapenden Closure?
Zusammenfassung
Sie haben Capture-Listen kennengelernt:
- Starkes self in einer gespeicherten escapenden Closure erzeugt einen Retain-Zyklus (Speicherleck)
[weak self]durchbricht ihn; self wird optional — verwenden Sieguard let selfunownedist nicht optional und schneller, führt aber zum Absturz, wenn self verschwunden ist- Non-Escaping-Closures benötigen keine Capture-Listen
Als Nächstes: Autoclosures.
Lerne Swift mit einem KI-Tutor — kostenlos
Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.
- Kurse
- 122
- Lektionen
- 409
Häufig gestellte Fragen
Ist die Lektion „Capture-Listen und Weak Self“ kostenlos?
Ja — der vollständige Text von „Capture-Listen und Weak Self“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Swift Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Capture-Listen und Weak Self“?
Vermeiden Sie Retain Cycles mit [weak self]. Du übst Swift Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Swift Academy zu starten?
Keine Vorkenntnisse erforderlich. Swift Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Capture-Listen und Weak Self“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Swift Academy-Lektion Code schreiben und ausführen?
Ja. Jede Swift Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Werte per Referenz erfassen
- Escaping Closures
- Capture-Listen und Weak Self
- Autoclosures