Sobes.tech
Middle

Swift-də capture siyahısı haqqında danış.

sobes.tech Süni İntellekt

AI-dan cavab

Swift-də capture list, closure-lər tərəfindən dəyişənlərin açıq şəkildə tutulmasını idarə etmək üçün istifadə olunur. Bu, xüsusən siniflər daxilində istifadə olunan closure-lərdə güclü referans döngülərindən qaçmağa kömək edir. Əsas capture növləri: weak və unowned.

Capture növü Təsviri Nə zaman istifadə edilməlidir
weak Dəyişəni opsional kimi tutar, referans sayğacını artırmaz. Dəyəri nil ola bilər. Closure obyekti, tutulmuş obyektdən daha uzun müddət yaşaya bilərsə.
unowned Dəyişəni referans sayğacını artırmadan tutar, amma güman edilir ki, tutulmuş obyekt closure mövcud olduğu müddətdə yaşayacaq. Opsional deyil. Closure obyekti və tutulmuş obyekt eyni ömre malikdirsə və tutulmuş obyekt, closure tamamlanmadan nil olmayacaqsa.

Capture list sintaksisi:

{ [capture list] (parametrlər) -> dönüşTipi in
    // kod
}

weak self istifadəsi nümunəsi:

class MyClass {
    var value = 0

    func doSomethingLater() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
            guard let self = self else { return } // nil yoxlaması
            self.value += 1
            print("Dəyər indi \(self.value)")
        }
    }
}

unowned self istifadəsi nümunəsi:

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 halda lazım deyil, çünki button ViewController mövcud olduğu müddətdə mövcuddur.
        // Amma closure, ViewController-dan uzun müddət yaşaya bilərsə, unowned uyğun ola bilər, əgər
        // self-in nil olacağına əminsinizsə.
        let action = { [unowned self] in
             self.view.backgroundColor = .blue
        }
        action()
    }
}

Yalnız self deyil, həm də closure daxilində əlçatan digər dəyişənləri tutmaq mümkündür. Məsələn, closure yaradılarkən dəyişənin dəyərini saxlamaq üçün:

func createIncrementer(initialValue: Int) -> () -> Int {
    var currentValue = initialValue
    return { [initialValue] in // initialValue-ni dəyər kimi tuturuq
        currentValue += 1
        print("İlkin dəyər \(initialValue)") // initialValue öz dəyərini saxlayır
        return currentValue
    }
}

let incrementer = createIncrementer(initialValue: 5)
print(incrementer()) // Nəticə: İlkin dəyər 5, sonra 6
print(incrementer()) // Nəticə: İlkin dəyər 5, sonra 7