ProgrammatieiOS ontwikkelaar

Beschrijf het werkmechanisme van defer in Swift, met welke grensgevallen en bijzonderheden men voorzichtig moet zijn?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

defer is een speciale constructie in Swift die het mogelijk maakt om een bepaalde codeblok uit te voeren net voordat je de scope van een functie verlaat, ongeacht of we de functie verlaten via een normale return of door een fout (throw). Defer is handig voor het vrijgeven van middelen, het terugdraaien van wijzigingen of het beëindigen van operaties.

Bijzonderheden van het werk:

  • Als er meerdere defer-instructies in een functie staan, worden ze uitgevoerd in omgekeerde volgorde (LIFO - last in, first out).
  • defer wordt uitgevoerd, zelfs bij het optreden van een fout (throw) of bij elke return uit de functie.
  • In een closure wordt defer beschouwd als behorend tot het lichaam van de closure, en niet op de plaats waar de closure wordt aangeroepen.

Voorbeeld:

func testDefer() { print("begin") defer { print("eerste defer") } defer { print("tweede defer") } print("eind") } // Zal weergeven: // begin // eind // tweede defer // eerste defer

Grensgevallen:

  • defer vangt waarden van variabelen op het moment dat defer verschijnt: als we variabelen in defer closure gebruiken, zijn veranderingen zichtbaar op het moment van uitvoering van defer.
  • Als de functie is voltooid met fatalError - wordt defer niet aangeroepen.

Vragend met een valstrik.

Zullen alle defer-blokken in de functie worden uitgevoerd als fatalError binnenin wordt aangeroepen?

Antwoord: Nee, als er een fatalError (of soortgelijke oncontroleerbare crashes) binnen de functie wordt aangeroepen, worden alle uitgestelde blokken via defer niet uitgevoerd. defer garandeert niet dat de code wordt uitgevoerd in gevallen van een noodstop van de applicatie.

Voorbeeld:

func foo() { defer { print("Defer 1") } fatalError("Oops") defer { print("Defer 2") } } foo() // geeft niets weer, er treedt een crash op

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp.


Verhaal

In het project werd defer gebruikt voor het sluiten van een bestandshandle. Bij het optreden van een fout gebruikten ze fatalError in plaats van een correcte throw, wat leidde tot een lek van een open bron, omdat defer niet werd uitgevoerd bij een crash.


Verhaal

In een functie waren meerdere defer-instructies, waarvan sommige afhankelijk waren van de toestand van lokale variabelen. De ontwikkelaar verwachtte dat de variabele een specifieke waarde zou hebben, maar deze waarde veranderde in defer door een ander deel van de code, en bij het uitvoeren van defer werd de actuele waarde gebruikt in plaats van de oude waarde, wat leidde tot een bug in het annuleren van een transactie op een verkeerd ID.


Verhaal

In een geneste closure werd een defer-blok geschreven, in de veronderstelling dat het zou worden uitgevoerd bij het verlaten van de externe functie. Als gevolg daarvan werd deze defer uitgevoerd bij het verlaten van de closure, en niet van de hele functie, waardoor de bron te vroeg werd vrijgegeven.