Les nombreuses réponses existantes bien écrites couvrent bien la question, mais je mentionnerai, en détail, un ajout qui, je crois, mérite d'être couvert.
Les observateurs de propriétés willSet
et didSet
peuvent être utilisés pour appeler des délégués, par exemple, pour des propriétés de classe qui ne sont jamais mises à jour que par interaction de l'utilisateur, mais où vous voulez éviter d'appeler le délégué lors de l'initialisation de l'objet.
Je citerai le commentaire voté par Klaas à la réponse acceptée:
Les observateurs willSet et didSet ne sont pas appelés lors de la première initialisation d'une propriété. Ils ne sont appelés que lorsque la valeur de la propriété est définie en dehors d'un contexte d'initialisation.
Ceci est assez soigné car cela signifie par exemple que la didSet
propriété est un bon choix de point de lancement pour les fonctions et rappels délégués, pour vos propres classes personnalisées.
Par exemple, considérons un objet de contrôle utilisateur personnalisé, avec une propriété clé value
(par exemple, la position dans le contrôle de notation), implémenté comme une sous-classe de UIView
:
// CustomUserControl.swift
protocol CustomUserControlDelegate {
func didChangeValue(value: Int)
// func didChangeValue(newValue: Int, oldValue: Int)
// func didChangeValue(customUserControl: CustomUserControl)
// ... other more sophisticated delegate functions
}
class CustomUserControl: UIView {
// Properties
// ...
private var value = 0 {
didSet {
// Possibly do something ...
// Call delegate.
delegate?.didChangeValue(value)
// delegate?.didChangeValue(value, oldValue: oldValue)
// delegate?.didChangeValue(self)
}
}
var delegate: CustomUserControlDelegate?
// Initialization
required init?(...) {
// Initialise something ...
// E.g. 'value = 1' would not call didSet at this point
}
// ... some methods/actions associated with your user control.
}
Après quoi, vos fonctions de délégué peuvent être utilisées dans, disons, certains contrôleurs de vue pour observer les changements clés dans le modèle CustomViewController
, tout comme vous utiliseriez les fonctions de délégué inhérentes UITextFieldDelegate
aux UITextField
objets for (par exemple textFieldDidEndEditing(...)
).
Pour cet exemple simple, utilisez un rappel délégué à partir didSet
de la propriété de classe value
pour indiquer à un contrôleur de vue que l'une de ses sorties a eu une mise à jour de modèle associée:
// ViewController.swift
Import UIKit
// ...
class ViewController: UIViewController, CustomUserControlDelegate {
// Properties
// ...
@IBOutlet weak var customUserControl: CustomUserControl!
override func viewDidLoad() {
super.viewDidLoad()
// ...
// Custom user control, handle through delegate callbacks.
customUserControl = self
}
// ...
// CustomUserControlDelegate
func didChangeValue(value: Int) {
// do some stuff with 'value' ...
}
// func didChangeValue(newValue: Int, oldValue: Int) {
// do some stuff with new as well as old 'value' ...
// custom transitions? :)
//}
//func didChangeValue(customUserControl: CustomUserControl) {
// // Do more advanced stuff ...
//}
}
Ici, la value
propriété a été encapsulée, mais généralement: dans des situations comme celles-ci, veillez à ne pas mettre à jour la value
propriété de l' customUserControl
objet dans la portée de la fonction déléguée associée (ici:) didChangeValue()
dans le contrôleur de vue, ou vous vous retrouverez avec récursion infinie.
get
&set
) doit essentiellement avoir une propriété calculée sur la base d'une autre propriété, par exemple la conversion d'une étiquettetext
en une annéeInt
.didSet
&willSet
sont là pour dire ... hé cette valeur a été définie, maintenant faisons ceci par exemple Notre dataSource a été mise à jour ... alors rechargeons la tableView afin qu'elle inclue de nouvelles lignes. Pour un autre exemple, voir la réponse de dfri sur la façon d'appeler les déléguésdidSet