Mi az a lezárás?
sobes.tech MI
Válasz az MI-től
A Swiftben a zárójel (closure) egy önálló funkcionális egység ({}), amely átadható és használható a kódban. A zárójelek képesek elfogni és tárolni hivatkozásokat bármilyen állandóra vagy változóra a kontextusból, ahol definiálva vannak.
Használati példák:
- Függvények argumentumaiként (pl. Completion Handlers).
- A kollekciók iterálásakor történő viselkedés meghatározására (pl.
map,filter,reduce,sortedmetódusok használatával). - Kód késleltetett végrehajtására.
Szintaxis:
// Alap szintaxis
{ (paraméterek) -> visszatérési típus in
utasítások
}
// Egy példa zárójel, amely Int-et fogad és String-et ad vissza
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Szám: \(number)"
}
Jellemzők:
- Automatikus változó elfogás (capturing values).
- A zárójelek típusainak explicit megadása nélkül is definiálhatók (szintaktikus cukor).
- Rövidített paraméternevek használata ($0, $1 stb.).
- A zárójel szintaxis (trailing closure syntax).
Változók elfogása:
A zárójel elfoghatja a környezetéből származó változókat. Alapértelmezés szerint hivatkozás szerint történik az elfogás. Ha a zárójel használata után a kiindulási változó már nem elérhető, a zárójel továbbra is hozzáférést biztosít hozzá.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Külső környezetből származó változó
let incrementer: () -> Int = { // Zárójel
runningTotal += amount // Elfogja a runningTotal-t és az amount-ot
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Kimenet: 10
print(incrementByTen()) // Kimenet: 20
Elfogási listák (Capture Lists):
Ezeket arra használják, hogy egyértelműen megadják, hogyan kell elfogni a változókat - érték szerint vagy hivatkozás szerint, valamint a ciklusok erős hivatkozásainak (retain cycles) elkerülésére.
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // self hivatkozás szerint, value érték szerint
print("self.value értéke: \(self.value)")
print("Elfogott érték: \(value)")
}
deinit {
print("A MyClass példány felszabadult")
}
}
Az erős hivatkozási ciklusok elkerülése érdekében a [weak self] vagy [unowned self] szintaxist használják.
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // gyenge hivatkozás self-re
guard let self = self else { return } // létezés ellenőrzése
// eredmény kezelése
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Aszinkron művelet...
}
}