Жабууну эмне деп айтат?
sobes.tech AI
AIден жооп
Swiftтеги жабык (closure) — бул өзүнчө функционалдык блок ({}), ал коддо өткөрүлүп жана колдонулушу мүмкүн. Жабыкдар кез келген константтарга жана өзгөрмөлөргө шилтемелерди ээлеп жана сактай алат, алардын аныкталган контекстинен.
Колдонуу мисалдары:
- Функциялардын аргументтери катары (мисалы, Completion Handlers).
- Коллекциялардын өтүүсүндө жүрүм-турумду аныктоо үчүн (мисалы,
map,filter,reduce,sortedметоддорун колдонуу менен). - Кодду кечиктирип иштетүү үчүн.
Синтаксис:
// Негизги синтаксис
{ (параметрлер) -> кайтарууТип in
билдирүүлөр
}
// Жабыктын мисалы, ал Int кабыл алып, String кайтарат
let integerToString: (Int) -> String = { (number: Int) -> String in
return "Сан: \(number)"
}
Мүнөздөмөлөр:
- Өзгөрмөлөрдү автоматтык түрдө ээлөө (capturing values).
- Параметрлердин жана кайтаруу маанисинин түрлөрүн так көрсөтпөстөн жабыктарды аныктоо мүмкүнчүлүгү (синтаксистик шекер).
- кыска аталыштарды колдонуу ($0, $1 жана башка).
- Жабыктын синтаксиси (trailing closure syntax).
Өзгөрмөлөрдү ээлөө:
Жабык өзүнүн чөйрөсүндөгү өзгөрмөлөрдү ээлей алат. Баштапкы ээлөө шилтемеси аркылуу болот. Эгер жабык баштапкы өзгөрмө чыккан соң колдонулса, ал дагы эле ага жетүүнү камсыздайт.
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0 // Чөйрөдөн келген өзгөрмө
let incrementer: () -> Int = { // Жабык
runningTotal += amount // runningTotal жана amount ээлейт
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Чыгуу: 10
print(incrementByTen()) // Чыгуу: 20
Ээлөө тизмелери (Capture Lists):
Бул өзгөрмөлөрдү так ээлөө үчүн колдонулат — мааниси боюнча же шилтемеси боюнча, ошондой эле күчтүү шилтемелер циклин алдын алуу үчүн (retain cycles):
class MyClass {
var value = 0
lazy var myClosure: () -> Void = { [self, value] in // self шилтемеси менен, value мааниси менен
print("self.value мааниси: \(self.value)")
print("Ээлөнгөн мааниси: \(value)")
}
deinit {
print("MyClass объектиси бошотулду")
}
}
Күчтүү шилтемелер циклин алдын алуу үчүн [weak self] же [unowned self] синтаксисин колдонуу керек:
class ViewController {
var dataFetcher: DataFetcher?
func fetchData() {
dataFetcher?.fetch { [weak self] result in // алсыз шилтеме self
guard let self = self else { return } // бар экенин текшерүү
// Натыйжаны иштетүү
}
}
}
class DataFetcher {
var completionHandler: ((Result<String, Error>) -> Void)?
func fetch(completion: @escaping (Result<String, Error>) -> Void) {
self.completionHandler = completion
// Асимхрондук операция...
}
}