Sobes.tech
Junior

Yopilish nima?

sobes.tech AI

AIdan javob

Swift'da yopilish (closure) — bu mustaqil funktsiya blokidir ({}), uni kodda uzatish va ishlatish mumkin. Yopilishlar, ularni aniqlagan kontekstdagi har qanday doimiy va o'zgaruvchilarga referenslarni ushlash va saqlash imkoniyatiga ega.

Foydalanish misollari:

  • Funktsiyalarning argumentlari sifatida (masalan, yakunlash handlerlari).
  • Kolleksiyalarni ro'yxatga olishda xatti-harakatni belgilash uchun (masalan, map, filter, reduce, sorted metodlaridan foydalanish).
  • Kodingizni kechiktirilgan bajarish uchun.

Sintaksis:

// Asosiy sintaksis
{ (parametrlar) -> qaytishTuri in
    bayonotlar
}

// Int qabul qiladigan va String qaytaradigan yopilish misoli
let integerToString: (Int) -> String = { (number: Int) -> String in
    return "Raqam: \(number)"
}

Xususiyatlar:

  • Avtomatik o'zgaruvchilarni ushlash.
  • Parametrlar va qaytish qiymatini aniq ko'rsatmasdan yopilishlarni belgilash imkoniyati (sintaktik shakar).
  • Parametrlar uchun qisqartirilgan nomlar ($0, $1 va boshqalar) foydalanish.
  • Trailing closure sintaksisi.

O'zgaruvchilarni ushlash:

Yopilish, o'z atrof-muhitidan o'zgaruvchilarni ushlashi mumkin. Standart holatda, u referens orqali amalga oshiriladi. Agar yopilish, asl o'zgaruvchidan chiqib ketganidan keyin ishlatilsa, u unga kirishni davom ettiradi.

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0 // Tashqi kontekstdagi o'zgaruvchi
    let incrementer: () -> Int = { // Yopilish
        runningTotal += amount // runningTotal va amount'ni ushlash
        return runningTotal
    }
    return incrementer
}

let incrementByTen = makeIncrementer(forIncrement: 10)
print(incrementByTen()) // Chiqish: 10
print(incrementByTen()) // Chiqish: 20

Ushlab olish ro'yxatlari (Capture Lists):

O'zgaruvchilar qanday ushlanishi kerakligini aniq belgilash uchun ishlatiladi - qiymat yoki referens orqali, shuningdek, kuchli referens sikllarini (retain cycles) oldini olish uchun.

class MyClass {
    var value = 0

    lazy var myClosure: () -> Void = { [self, value] in // self'ni referens bilan, value'ni qiymat bilan ushlash
        print("self.value ning qiymati: \(self.value)")
        print("Ushlangan qiymat: \(value)")
    }

    deinit {
        print("MyClass instansiyasi bo'shatildi")
    }
}

Klass ob'ektlarini ushlab turishda kuchli referens sikllarini oldini olish uchun [weak self] yoki [unowned self] sintaksisidan foydalaniladi.

class ViewController {
    var dataFetcher: DataFetcher?

    func fetchData() {
        dataFetcher?.fetch { [weak self] result in // Zaif referens self
            guard let self = self else { return } // self mavjudligini tekshirish
            // Natija bilan ishlash
        }
    }
}

class DataFetcher {
    var completionHandler: ((Result<String, Error>) -> Void)?

    func fetch(completion: @escaping (Result<String, Error>) -> Void) {
        self.completionHandler = completion
        // Asinxron operatsiya...
    }
}