ARC (Automatic Reference Counting) is een systeem voor automatisch geheugenbeheer in Swift. Bij elke nieuwe sterke verwijzing naar een object wordt de teller verhoogd; bij verwijdering wordt deze verlaagd. Wanneer de teller nul is, wordt het object vrijgegeven.
Retain cycle is een situatie waarin objecten elkaar sterke verwijzingen geven en nooit worden vrijgegeven.
Manieren om dit te voorkomen:
protocol SomeDelegate: AnyObject { } class Owner { weak var delegate: SomeDelegate? }
[weak self] of [unowned self]:class Example { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doSomething() } } func doSomething() { } }
Wat is het verschil tussen [weak self] en [unowned self] binnen een closure? Welke type verwijzingen moet je gebruiken en wanneer?
Antwoord:
[weak self] creëert een optionele verwijzing; self kan nil zijn, daarom wordt meestal veilige extractie self? gebruikt.[unowned self] creëert een niet-optionele verwijzing en verhoogt de teller NIET; als het object al is vrijgegeven en er een toegang plaatsvindt, zal het crashen.[unowned self] worden gebruikt.Voorbeeld:
someClosure = { [weak self] in self?.doTask() } // of (als self 100% langer leeft dan de closure): someClosure = { [unowned self] in doTask() }
Verhaal
In een project ontstond een situatie van een retain cycle tussen ViewController en zijn closure, gekoppeld aan de verwerking van de druk. De ViewController verwees naar de closure, die self vastlegde met een sterke verwijzing. Hierdoor werden de controller en al zijn gegevens niet vrijgegeven na het sluiten van het scherm. Het probleem werd opgelost door
[weak self]in de closure in te voeren.
Verhaal
Implementatie van het delegate-patroon tussen twee objecten. De delegate was als een sterke (
strong) eigenschap verklaard. Hierdoor werd de hoofdobject niet gedealloceerd bij het verwijderen uit het geheugen, wat leidde tot geheugenlek. Na het omzetten van de delegate naar weak verdween het probleem.
Verhaal
Voor animatie werd een closure binnen UIView gebruikt. De closure legde self vast met
[unowned self]. Toen de view werd verwijderd vóór het voltooien van de animatie, crashte de app door de toegang tot de al vrijgegeven self. Oplossing — gebruik van[weak self]en verplichte controle op niet-nil self binnen de closure.