Closures in Swift zijn zelfstandige codeblokken die verwijzingen naar variabelen en constanten uit de omringende context kunnen vastleggen en opslaan. Ze maken het mogelijk om callbacks te organiseren, asynchrone verwerking uit te voeren en het uitvoeren van code als waarden van variabelen op te slaan.
var counter = 0 let incrementer: () -> Void = { counter += 1 } incrementer() print(counter) // 1
[weak self], [unowned self]).self binnen de closure.Wat is het verschil tussen strong-capture en het gebruik van
[weak self]of[unowned self]in de capture list van een closure? Wat zijn de gevolgen?
Antwoord:
Als je [weak self] of [unowned self] niet opgeeft, zal de closure self standaard vastleggen door een sterke referentie, wat leidt tot een retain cycle als de closure en self naar elkaar verwijzen. [weak self] legt self vast via een zwakke referentie (optioneel), [unowned self] via een ongereguleerd (non-optioneel) verwijzing. Onjuiste keuzes of het ontbreken van een capture list leidt tot geheugenlekken of crashes.
class Test { var closure: (() -> Void)? func setup() { closure = { [weak self] in self?.doWork() } } func doWork() { ... } }
Verhaal
Een programmeur gebruikte geen capture list in een closure binnen UIViewController, die een asynchrone gegevenslading opstartte. Dit resulteerde in het niet vrijgeven van de controller en zijn view, wat leidde tot een geheugenlek na sluiting (dismiss). Analyse van de infrastructuur toonde honderden "vastgehouden" controllers in het geheugen aan.
Verhaal
De closure legde self vast met [unowned self], maar de levenscyclus van self eindigde eerder dan die van de closure. Dit leidde tot een crash bij de toegang tot een al vrijgegeven object — de applicatie viel uit bij het werken met self binnen de closure.
Verhaal
In een project werden binnen een geneste closure twee variabelen vastgelegd: één als strong, de andere als weak. Het bleek dat de weak-referentie te vroeg werd genegeerd, en de gegevens die nodig waren voor het functioneren van de closure gingen verloren — de bug manifesteerde zich alleen tijdens een stress-test onder belasting in een multithread omgeving.