J'ai une idée de ce qu'il faut utiliser et quand, mais l'usage exact n'est toujours pas clair pour moi. Quelqu'un peut-il m'expliquer avec un exemple ?
Réponses
Trop de publicités?Utilisez un délégué si vous voulez parler à un seul objet. Par exemple, un tableView a un délégué - un seul objet doit être chargé de s'en occuper.
Utilisez les notifications si vous souhaitez informer tout le monde que quelque chose s'est produit. Par exemple, dans les situations de mémoire faible, une notification est envoyée pour indiquer à votre application qu'il y a eu une alerte mémoire. Comme de nombreux objets de votre application pourraient vouloir réduire leur utilisation de la mémoire, il s'agit d'une notification.
Je ne pense pas du tout que KVO soit une bonne idée et j'essaie de ne pas l'utiliser mais, si vous voulez savoir si une propriété a changé, vous pouvez écouter les changements.
J'espère que cela vous aidera.
PS Cela résume la raison pour laquelle je pense que KVO est cassé.
Utilisez un délégué lorsqu'il existe une relation "maître/esclave" (le délégué connaît la classe et la classe connaît le délégué), avec une classe située plus haut dans la hiérarchie des contrôles, et lorsqu'il est clair qu'il n'y aura pas de situations où d'autres éléments (principalement l'interface utilisateur) seront intéressés par ce que la classe a à dire.
Utilisez les notifications lorsque la classe n'est pas intéressée à savoir qui écoute et combien ils sont, n'importe qui et n'importe quel nombre peut s'inscrire pour les notifications.
La KVO est utile pour écouter "à l'insu de la classe", bien que ce ne soit évidemment pas le cas, la classe sur laquelle la KVO est appliquée ne doit pas être modifiée.
La délégation est un modèle de conception que vous utilisez lorsque vous voulez qu'un autre objet modifie le comportement de l'expéditeur. Exemple : les fenêtres de terminal évitent d'afficher les lignes ou les caractères qui sont coupés par les bords de la fenêtre, car le délégué de la fenêtre de terminal modifie la taille de la fenêtre pour s'en assurer.
La notification est un modèle à utiliser lorsque vous n'avez pas besoin de réponse. Exemple : vous recevez une notification indiquant que le système est sur le point de se mettre en veille. L'expéditeur de cette notification ne se soucie pas de ce que vous faites à ce sujet.
Modèle de délégué, NotificationCenter, KVO
Délégué
delegate
est un modèle de conception qui peut être lié au modèle structurel (modèle Decorator ou Wrapper de GoF) qui ajoute des comportements et des responsabilités à un objet sans modifier son code. Vous pouvez déplacer une certaine logique dans une autre classe d'aide ou l'utiliser comme un squelette. C'est une alternative à l'héritage. Techniquement, il utilise association
[À propos] . Le langage Kotlin prend en charge delegate
sur la couche de langage. Quant à iOS, il est généralement utilisé pour Loose coupling
pour communiquer entre les classes Class1 <-> Class2
sans Retain cycle
[À propos] donde SomeClass1 -> SomeClass2
y SomeClass2 weak-> SomeClass1
protocol SomeProtocol {
func foo()
}
class SomeClass1: SomeProtocol {
let someClass2 = SomeClass2()
init() {
someClass2.delegate = self
}
func foo() {
print("foo is called")
}
}
class SomeClass2 {
weak var delegate: SomeProtocol?
func onButtonTap() {
delegate?.foo()
}
}
Centre de notification
NotificationCenter or NSNotificationCenter(Objective-C)
(pas les notifications à distance (Push) ou locales) est une sorte de publish/subscribe event bus
. Vous avez NotificationCenter
objet singleton qui est un point unique pour n'importe qui pour envoyer ou recevoir un événement. Vous pouvez l'utiliser pour envoyer des événements à travers toute l'application et n'importe qui peut l'interrompre. Un tel système est rapide à développer mais difficile à supporter. C'est aussi une sorte de Loose coupling
système.
Vous pouvez utiliser l'API suivante de NotificationCenter :
post(name: object: userInfo:)
addObserver(_ observer: selector: name: object:)
removeObserver(_ observer: selector: object:)
Par exemple, le système affiche ou cache le clavier.
NotificationCenter.default.addObserver(self, selector: #selector(MyViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(MyViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
@objc func keyboardWillShow(_ notification:Notification) {
}
@objc func keyboardWillHide(_ notification:Notification) {
}
KVO
KVO
- Observation de la valeur d'une clé. Observer les changements de valeur d'une propriété supportée par Objective-C. Vous pouvez l'utiliser lorsque vous avez besoin d'être informé de certains changements sur un objet sans aucune requête.
Objectif-C - @property
[À propos] qui utilise willChangeValueForKey
y didChangeValueForKey
para KVO
*Notes
- Si vous passez outre
willChangeValueForKey
,didChangeValueForKey
le siteobserveValueForKeyPath
n'est pas tiré -
Si vous utilisez iVar [À propos] vous êtes responsable d'appeler
willChangeValueForKey
,didChangeValueForKey
import "SomeClass.h"
@interface SomeClass() @property (nonatomic, strong) NSString *someVariable; @end
@implementation SomeClass
-
(void) foo {
[self addObserver: self forKeyPath: @"someVariable" options: NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context: nil];self.someVariable = @"set someVariable"; }
-
(void)observeValueForKeyPath:(NSString )keyPath ofObject:(id)object change:(NSDictionary )change context:(void *)context { if ([keyPath isEqualToString:@"someVariable"]) { NSLog(@"%@", change); } }
@end
-
Swift - NSObject
y @objc dynamic
[À propos]
class SomeClass1 : NSObject {
@objc dynamic var v = 0
}
class SomeClass2 {
var kvoToken: NSKeyValueObservation?
func subscribe(someClass1: SomeClass1) {
kvoToken = someClass1.observe(\.v, options: .new) { (object, change) in
guard let value = change.newValue else { return }
print("New value: \(value)")
}
}
deinit {
kvoToken?.invalidate()
}
}
ou
public class SomeClass: NSObject
public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
}
}
func foo() {
someClass1.addObserver(self, forKeyPath: "v", options: .new, context: nil)
}
- Réponses précédentes
- Plus de réponses