Sobes.tech
Middle

Swiftтеги capture тизмеси жөнүндө айтып бер.

sobes.tech AI

AIден жооп

Swiftте capture list колдонулат өзгөрмөлөрдү ачык башкаруу үчүн (closures). Бул күчтүү шилтемелер циклин алдын алууга жардам берет, өзгөчө self колдонулганда, ал класстарда колдонулат. Негизги захват түрлөрү: weak жана unowned.

Захват түрү Түшүндүрмө Кайсы учурда колдонуу керек
weak Өзгөрмөнү опционал катары захват кылат, шилтемелер санын көбөйтпөйт. Анын мааниси nil болушу мүмкүн. Эгер захват кылынган объект жашай алса, ал объекттен узакка жашай алса.
unowned Өзгөрмөнү шилтемелер санын көбөйтпөйт, бирок захват кылынган объект жашай берет деп эсептелет, ал nil болбойт. Эгер заттар бир убакта жашаса жана захват кылынган объект 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 дагы бар.
        // Эгер заттар бир убакта жашаса, 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