En closure fanger de variabler, den refererer til, og holder dem i live. Når en closure fanger self, og self også holder closuren (en lagret property), holder de hinanden i live for evigt — en , der lækker hukommelse. En som bryder den cyklus.
En closure fanger de variabler, den refererer til, og holder dem i live. Når en closure fanger self, og self også holder closuren (en lagret property), holder de hinanden i live for evigt — en , der lækker hukommelse. En som bryder den cyklus.
[weak self]ARC frigiver et objekt, når dets reference count når nul. En stærk capture øger den tælling.
final class Downloader {
var onDone: (() -> Void)? // stored closure -> strong
func start() {
// BAD: closure captures self strongly, self holds closure -> cycle
onDone = { self.cleanup() }
// GOOD: weak capture, self can deallocate
onDone = { [weak self] in
guard let self else { return } // safely unwrap; bail if gone
self.cleanup()
}
}
func cleanup() {}
}
[weak self] — self bliver en optional; den er nil, hvis objektet blev frigivet. Sikkert standardvalg, når objektet kan overleve closuren.[unowned self] — non-optional, ingen ARC-overhead, men crasher, hvis self allerede er væk. Brug kun, når self er garanteret at overleve closuren.Task { [weak self] in
let data = await self?.fetch() // self? short-circuits if deallocated
}
Non-escaping closures (fx map, filter, forEach) kører synkront og frigiver captures øjeblikkeligt — ingen cyklus, ingen [weak self] nødvendig. Risikoen er ved escaping, lagrede closures: completion handlers, Timer, NotificationCenter, Combine-sinks, delegate-blokke.
Retain cycles er den mest almindelige memory leak i iOS, og de er usynlige, indtil Instruments viser voksende hukommelse. At vide præcist hvornår en closure escaper og hvorfor [weak self] er nødvendig — kontra at gribe til den refleksivt overalt — adskiller ingeniører, der forstår ARC, fra dem, der cargo-culter det.
Et bibliotek af IT-interviewspørgsmål med detaljerede svar — fra Junior til Senior.
Donér