Middle
Räägi mulle capture listist Swiftis.
sobes.tech AI
Vastus AI-lt
Swiftis kasutatakse capture listi, et selgelt hallata muutujate haaramist suletistes (closures). See aitab vältida tugevaid viidetsüklusi, eriti kui kasutatakse self-i suletistes, mis on kasutusel klassides. Peamised haaratüübid on: weak ja unowned.
| Haaratüüp | Kirjeldus | Millal kasutada |
|---|---|---|
weak |
Haarab muutuja valikulisena, mitte suurendades viidete arvu. Selle väärtus võib muutuda nil-iks. |
Kui haaratud objekt võib elada üle haaratud objekti. |
unowned |
Haarab muutuja ilma viidete arvu suurendamata, eeldades, et haaratud objekt elab seni, kuni suletis eksisteerib. Ei ole valikuline. | Kui suletis ja haaratud objekt on sama eluea ning haaratud objekt ei muutu nil-iks suletise lõpuks. |
Capture listi süntaks:
{ [capture list] (parameetrid) -> tagastatüüp in
// kood
}
Näide weak self kasutamisest:
class MyClass {
var value = 0
func doSomethingLater() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
guard let self = self else { return } // `nil` kontroll
self.value += 1
print("Väärtus on nüüd \(self.value)")
}
}
}
Näide unowned self kasutamisest:
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 ei ole selles olukorras vajalik, kuna nupp eksisteerib seni, kuni eksisteerib ViewController.
// Kui suletis võiks elada üle ViewControlleri, siis unowned oleks sobiv, kui oleme kindlad,
// et self ei muutu `nil`-iks.
let action = { [unowned self] in
self.view.backgroundColor = .blue
}
action()
}
}
Haarata võib mitte ainult self, vaid ka teisi muutujaid, mis on suletises kättesaadavad. Näiteks, et salvestada muutuja väärtus selle loomise hetkel:
func createIncrementer(initialValue: Int) -> () -> Int {
var currentValue = initialValue
return { [initialValue] in // Haarame initialValue väärtuse järgi
currentValue += 1
print("Algväärtus oli \(initialValue)") // initialValue säilitab oma väärtuse
return currentValue
}
}
let incrementer = createIncrementer(initialValue: 5)
print(incrementer()) // Väljund: Algväärtus oli 5, siis 6
print(incrementer()) // Väljund: Algväärtus oli 5, siis 7