Sobes.tech
Middle

պատմիր Swift-ում capture ցուցակի մասին։

sobes.tech AI

Պատասխան AI-ից

Swift- ում capture list-ը օգտագործվում է փոփոխականների բացահայտ կառավարման համար փակագծերում (closures): Սա օգնում է խուսափել ուժեղ ռեֆերենցիայի ցիկլերից, հատկապես այն ժամանակ, երբ օգտագործվում է self փակագծերի ներսում, որոնք օգտագործվում են դասարաններում: Հիմնական capture տեսակները՝ weak և unowned են:

Capture տեսակ Նկարագրություն Երբ օգտագործել
weak Հավաքում է փոփոխականը որպես ընտրանքային, առանց ռեֆերենցիայի հաշվիչը բարձրացնելու: Նրա արժեքը կարող է դառնալ nil: Երբ օբյեկտը փակագծի կարող է գոյատևել բռնված օբյեկտից:
unowned Հավաքում է փոփոխականը առանց ռեֆերենցիայի հաշվիչը բարձրացնելու, բայց ենթադրվում է, որ բռնված օբյեկտը կշարունակի գոյատևել, մինչեւ փակագծի ավարտը: Չի լինել ընտրանքային: Երբ փակագիծը եւ բռնված օբյեկտը ունեն նույն կյանքի ժամկետը, եւ բռնված օբյեկտը nil չի դառնա մինչեւ փակագծի ավարտը:

Capture list-ի սինտաքսիս:

{ [capture list] (պարամետրեր) -> վերադարձվող տեսակ in
    // կոդ
}

Օրինակ՝ weak self օգտագործելու համար:

class MyClass {
    var value = 0

    func doSomethingLater() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
            guard let self = self else { return } // `nil` ստուգում
            self.value += 1
            print("Արժեքը այժմ \(self.value)")
        }
    }
}

Օրինակ՝ unowned self օգտագործելու համար:

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 այս դեպքում անհրաժեշտ չէ, քանի որ բիթոնը գոյություն ունի, քանի դեռ կա ViewController-ը:
        // Բայց եթե փակագիծը կարող է գոյատևել ViewController-ից, unowned-ը կարող է լինել տեղին, եթե վստահ ենք,
        // որ self-ը `nil` չի դառնա:
        let action = { [unowned self] in
             self.view.backgroundColor = .blue
        }
        action()
    }
}

Անհրաժեշտ է, որ ոչ միայն self-ը, այլ նաև այլ փոփոխականներ, որոնք հասանելի են փակագծում, բռնվեն: Օրինակ՝ փոփոխականի արժեքը պահելու համար այն պահին, երբ ստեղծվում է փակագիծը:

func createIncrementer(initialValue: Int) -> () -> Int {
    var currentValue = initialValue
    return { [initialValue] in // բռնում ենք initialValue արժեքով
        currentValue += 1
        print("Առաջին արժեքը եղել է \(initialValue)") // initialValue պահում է իր արժեքը
        return currentValue
    }
}

let incrementer = createIncrementer(initialValue: 5)
print(incrementer()) // Արտածում՝ Առաջին արժեքը եղել է 5, հետո 6
print(incrementer()) // Արտածում՝ Առաջին արժեքը եղել է 5, հետո 7