Sobes.tech
Middle

Swift'da capture ro'yxati haqida gapiring.

sobes.tech AI

AIdan javob

Swift'da capture list, closure'lar tomonidan o'zgaruvchilarni aniq ushlab qolishni boshqarish uchun ishlatiladi. Bu, ayniqsa, sinflar ichida ishlatiladigan closure'larda kuchli referens tsikllaridan qochishga yordam beradi. Asosiy ushlash turlari: weak va unowned.

Uslub turi Tavsifi Qachon foydalaniladi
weak O'zgaruvchini opsional sifatida ushlab qoladi, referenslar sonini oshirmaydi. Uning qiymati nil bo'lishi mumkin. Closure obyekti, ushlab qolingan obyektdan uzoqroq yashashi mumkin bo'lsa.
unowned O'zgaruvchini referenslar sonini oshirmasdan ushlab qoladi, lekin ushlab qolingan ob'ekt, closure mavjud bo'lsa, yashaydi deb faraz qilinadi. Opsional emas. Closure obyekti va ushlab qolingan ob'ekt bir xil hayot davomiga ega bo'lsa va ushlab qolingan ob'ekt, closure tugashidan oldin nil bo'lmaydi.

Capture list sintaksisi:

{ [capture list] (parametrlar) -> returnType in
    // kod
}

weak self misoli:

class MyClass {
    var value = 0

    func doSomethingLater() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
            guard let self = self else { return } // nil tekshiruvi
            self.value += 1
            print("Qiymat endi \(self.value)")
        }
    }
}

unowned self misoli:

class ViewController: UIViewController {
    var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        button = UIButton(type: .system)
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
    }

    @objc func buttonTapped() {
        // unowned self bu holatda kerak emas, chunki button, ViewController mavjud bo'lsa, mavjud bo'ladi.
        // Ammo, agar closure, ViewController'dan uzoq yashash imkoniyatiga ega bo'lsa, unowned mos keladi, agar
        // self nil bo'lmaydi deb ishonch hosil qilsangiz.
        let action = { [unowned self] in
             self.view.backgroundColor = .blue
        }
        action()
    }
}

Faqat self ni emas, balki, closure ichida mavjud bo'lgan boshqa o'zgaruvchilarni ham ushlab qolish mumkin. Masalan, closure yaratilgan paytda o'zgaruvchining qiymatini saqlash uchun:

func createIncrementer(initialValue: Int) -> () -> Int {
    var currentValue = initialValue
    return { [initialValue] in // initialValue ni qiymat sifatida ushlab qoladi
        currentValue += 1
        print("Boshlang'ich qiymat \(initialValue)") // initialValue o'z qiymatini saqlaydi
        return currentValue
    }
}

let incrementer = createIncrementer(initialValue: 5)
print(incrementer()) // Natija: Boshlang'ich qiymat 5, keyin 6
print(incrementer()) // Natija: Boshlang'ich qiymat 5, keyin 7