Sobes.tech
Junior

Жабууну эмне деп айтат?

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
        // Асимхрондук операция...
    }
}