Kas yra uždarymas?
sobes.tech AI
Atsakymas iš AI
Užbaigimas (closure) Swift kalboje yra savarankiškas funkcionalumo blokas ({}), kuris gali būti perduotas ir naudojamas kode. Užbaigimai gali įgyti ir saugoti nuorodas į bet kokias konstantas ir kintamuosius iš konteksto, kuriame jie apibrėžti.
Naudojimo pavyzdžiai:
- Kaip funkcijų argumentai (pavyzdžiui, Completion Handlers).
- Apibrėžiant elgseną kolekcijų iteracijai (pavyzdžiui, naudojant
map,filter,reduce,sortedmetodus). - Kodui vėliau vykdyti.
Sintaksė:
// Pagrindinė sintaksė
{ (parametrai) -> grąžinimoTipas in
sakiniai
}
// Užbaigimo pavyzdys, priimantis Int ir grąžinantis String
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Skaičius: \(number)"
}
Savybės:
- Automatinis kintamųjų įsitraukimas (capturing values).
- Galimybė apibrėžti užbaigimus be aiškaus parametrų ir grąžinamos vertės tipo nurodymo (sintaksinis cukrus).
- Naudojant sutrumpintus parametrų pavadinimus ($0, $1 ir t.t.).
- Užbaigimo sintaksė (trailing closure syntax).
Įsitraukimo sąrašai:
Užbaigimas gali įsitraukti į savo aplinką esančius kintamuosius. Pagal numatytuosius nustatymus, įsitraukimas vyksta nuoroda. Jei užbaigimas naudojamas po to, kai originalus kintamasis išėjo iš apimties, užbaigimas vis tiek išlaiko prieigą prie jo.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Išorinis kontekstas
let incrementer: () -> Int = { // Užbaigimas
runningTotal += amount // Įsitraukia į runningTotal ir amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Išvestis: 10
print(incrementByTen()) // Išvestis: 20
Įsitraukimo sąrašai:
Naudojami aiškiai nurodyti, kaip turi būti įsitraukta kintamieji - reikšme ar nuoroda, taip pat siekiant išvengti stiprių ciklų (retain cycles).
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // įsitraukia self nuoroda, value reikšme
print("self.value reikšmė: \(self.value)")
print("Įsitraukta reikšmė: \(value)")
}
deinit {
print("MyClass egzempliorius atlaisvintas")
}
}
Siekiant išvengti stiprių ciklų, įsitraukiant į objektus, naudojama sintaksė [weak self] arba [unowned self]:
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // silpna nuoroda į self
guard let self = self else { return } // patikrinimas, ar self egzistuoja
// rezultatų apdorojimas
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Asinchroninė operacija...
}
}