ProgrammatieiOS ontwikkelaar

Wat is ARC in Swift? Hoe voorkom je retain cycles bij het werken met closures en delegaten?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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:

  • Voor delegatie-objecten gebruik een zwakke verwijzing:
protocol SomeDelegate: AnyObject { } class Owner { weak var delegate: SomeDelegate? }
  • Voor closures gebruik [weak self] of [unowned self]:
class Example { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doSomething() } } func doSomething() { } }

Misleidende vraag.

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.
  • De keuze hangt af van de bedrijfslogica: als de closure gegarandeerd niet langer leeft dan self, kan [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() }

Voorbeelden van echte fouten door onwetendheid over de nuances van het onderwerp.


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.