Wat is een closure?
sobes.tech AI
Antwoord van AI
De sluiting (closure) in Swift is een zelfstandige blok functionaliteit ({}) dat kan worden doorgegeven en gebruikt in de code. Sluitingen kunnen referenties vastleggen en opslaan naar elke constante en variabele uit de context waarin ze zijn gedefinieerd.
Voorbeelden van gebruik:
- Als argumenten van functies (bijvoorbeeld, voltooiingshandlers).
- Om gedrag te definiëren bij het enumereren van collecties (bijvoorbeeld, met behulp van methoden
map,filter,reduce,sorted). - Voor het uitstellen van code-uitvoering.
Syntax:
// Basis syntax
{ (parameters) -> returnType in
statements
}
// Voorbeeld van een sluiting die een Int accepteert en een String retourneert
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Nummer: \(number)"
}
Kenmerken:
- Automatisch vastleggen van variabelen.
- Mogelijkheid om sluitingen te definiëren zonder expliciet de typen van parameters en de returnwaarde aan te geven (sucrosyntaxis).
- Gebruik van verkorte namen voor parameters ($0, $1, etc.).
- Syntax van sluiting met trailing closure.
Vastleggen van variabelen:
Een sluiting kan variabelen uit zijn omgeving vastleggen. Standaard gebeurt de vastlegging per referentie. Als een sluiting wordt gebruikt nadat de oorspronkelijke variabele uit het bereik is, behoudt de sluiting nog steeds toegang tot deze.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Variabele uit externe context
let incrementer: () -> Int = { // Sluiting
runningTotal += amount // Vangt runningTotal en amount vast
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Uitvoer: 10
print(incrementByTen()) // Uitvoer: 20
Vastleglijsten (Capture Lists):
Worden gebruikt om expliciet aan te geven hoe variabelen moeten worden vastgelegd - per waarde of per referentie, en om sterke referentiecirkels (retain cycles) te voorkomen.
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // Vastleggen van self per referentie, value per waarde
print("Waarde van self.value: \(self.value)")
print("Vastgelegde waarde: \(value)")
}
deinit {
print("MyClass instantie vrijgegeven")
}
}
Om sterke referentiecirkels te voorkomen bij het vastleggen van klasse-objecten, wordt de syntax [weak self] of [unowned self] gebruikt.
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // Zwakke referentie naar self
guard let self = self else { return } // Controle op bestaan van self
// Verwerking van result
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Asynchrone operatie...
}
}