Čo je to uzáver?
sobes.tech AI
Odpoveď od AI
Zatvorka (closure) v Swift je samostatný blok funkčnosti ({}), ktorý môže byť odovzdaný a použitý v kóde. Zatvorky môžu zachytiť a uložiť odkazy na akékoľvek konštanty a premenné z kontextu, v ktorom sú definované.
Príklady použitia:
- Ako argumenty funkcií (napríklad, Completion Handlers).
- Na definovanie správania pri prechádzaní kolekcií (napríklad, pomocou metód
map,filter,reduce,sorted). - Na odložené vykonanie kódu.
Syntax:
// Základná syntax
{ (parametre) -> návratovýTyp in
príkazy
}
// Príklad zatvorky, ktorá prijíma Int a vracia String
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Číslo: \(number)"
}
Vlastnosti:
- Automatické zachytávanie premenných (capturing values).
- Možnosť definovať zatvorky bez explicitného určenia typov parametrov a návratovej hodnoty (syntaktický cukor).
- Použitie skrátených mien parametrov ($0, $1 a pod.).
- Syntax zatvorky (trailing closure syntax).
Zachytávanie premenných:
Zatvorka môže zachytiť premenné zo svojho okolia. Podľa predvoleného správania sa zachytávanie vykonáva odkazom. Ak sa zatvorka používa po tom, čo pôvodná premenná opustila oblasť platnosti, zatvorka si stále zachová prístup k nej.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Premenná z vonkajšieho prostredia
let incrementer: () -> Int = { // Zatvorka
runningTotal += amount // Zachytáva runningTotal a amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Výstup: 10
print(incrementByTen()) // Výstup: 20
Zoznamy zachytávania (Capture Lists):
Používajú sa na explicitné určenie, ako majú byť premenné zachytené - hodnotou alebo odkazom, a tiež na zabránenie silných cyklov odkazov (retain cycles).
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // Zachytávanie self odkazom, value hodnotou
print("Hodnota self.value: \(self.value)")
print("Zachytená hodnota: \(value)")
}
deinit {
print("Inštancia MyClass bola uvoľnená")
}
}
Na prevenciu silných cyklov pri zachytávaní objektov tried sa používa syntax [weak self] alebo [unowned self].
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // slabá referencia na self
guard let self = self else { return } // kontrola existencie self
// spracovanie result
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Asynchrónna operácia...
}
}