Co je to uzávěr?
sobes.tech AI
Odpověď od AI
Závěr (closure) ve Swiftu je samostatný blok funkčnosti ({}), který lze předat a použít v kódu. Závěry mohou zachytit a uložit odkazy na jakékoli konstanty a proměnné z kontextu, ve kterém jsou definovány.
Příklady použití:
- Jako argumenty funkcí (například Completion Handlers).
- Pro definování chování při iteraci kolekcí (například pomocí metod
map,filter,reduce,sorted). - Pro odložené provádění kódu.
Syntaxe:
// Základní syntaxe
{ (parametry) -> návratovýTyp in
příkazy
}
// Příklad závěru, který přijímá Int a vrací String
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Číslo: \(number)"
}
Vlastnosti:
- Automatické zachytávání proměnných (capturing values).
- Možnost definovat závěry bez explicitního určení typů parametrů a návratové hodnoty (syntaktický cukr).
- Použití zkrácených jmen parametrů ($0, $1 atd.).
- Syntaxe závěrečného bloku (trailing closure syntax).
Zachytávání proměnných:
Závěr může zachytit proměnné z okolí. Výchozí chování je zachytávání odkazem. Pokud je závěr použit po tom, co původní proměnná opustila oblast platnosti, závěr si stále uchovává přístup k ní.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Proměnná z vnějšího prostředí
let incrementer: () -> Int = { // Závěr
runningTotal += amount // Zachytává runningTotal a amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Výstup: 10
print(incrementByTen()) // Výstup: 20
Seznamy zachytávání (Capture Lists):
Používají se k explicitnímu určení, jak mají být proměnné zachyceny - hodnotou nebo odkazem, a také k prevenci silných cyklů odkazů (retain cycles).
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // Zachytávání self odkazem, value hodnotou
print("Hodnota self.value: \(self.value)")
print("Zachycená hodnota: \(value)")
}
deinit {
print("Instance MyClass byla uvolněna")
}
}
Pro prevenci silných cyklů při zachytávání objektů tříd se používá syntaxe [weak self] nebo [unowned self].
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // slabé zachycení self
guard let self = self else { return } // kontrola existence self
// zpracování result
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Asynchronní operace...
}
}