Sobes.tech
Middle

Vertel me over de capture list in Swift.

sobes.tech AI

Antwoord van AI

De capture list in Swift wordt gebruikt om expliciet het vastleggen van variabelen door closures te beheren. Dit helpt om sterke referentiecycli te voorkomen, vooral bij het werken met self in closures die binnen klassen worden gebruikt. De belangrijkste typen vastlegging zijn: weak en unowned.

Type vastlegging Beschrijving Wanneer gebruiken
weak Vangt de variabele als optioneel, zonder de referentieteller te verhogen. De waarde kan nil worden. Wanneer het closure-object langer kan bestaan dan het vastgelegde object.
unowned Vangt de variabele zonder de referentieteller te verhogen, maar wordt aangenomen dat het vastgelegde object zal blijven bestaan zolang het closure-object bestaat. Niet optioneel. Wanneer het closure-object en het vastgelegde object dezelfde levensduur hebben, en het vastgelegde object niet nil zal worden voordat het closure-object eindigt.

Syntax van de capture list:

{ [capture list] (parameters) -> returnType in
    // code
}

Voorbeeld van gebruik van 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-check
            self.value += 1
            print("Waarde is nu \(self.value)")
        }
    }
}

Voorbeeld van gebruik van 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 is in dit geval niet nodig, omdat de button bestaat zolang de ViewController bestaat.
        // Maar als het closure langer zou kunnen bestaan dan de ViewController, zou unowned passend zijn als
        // je zeker weet dat self niet nil wordt.
        let action = { [unowned self] in
             self.view.backgroundColor = .blue
        }
        action()
    }
}

Je kunt niet alleen self vastleggen, maar ook andere variabelen die binnen de closure toegankelijk zijn. Bijvoorbeeld, om de waarde van een variabele op het moment van het maken van de closure op te slaan:

func createIncrementer(initialValue: Int) -> () -> Int {
    var currentValue = initialValue
    return { [initialValue] in // capture initialValue als waarde
        currentValue += 1
        print("Initiële waarde was \(initialValue)") // initialValue behoudt zijn waarde
        return currentValue
    }
}

let incrementer = createIncrementer(initialValue: 5)
print(incrementer()) // Output: Initiële waarde was 5, daarna 6
print(incrementer()) // Output: Initiële waarde was 5, daarna 7