Lorsque vous observez une valeur sur un objet à l'aide de addObserver:forKeyPath:options:context:
, vous souhaiterez éventuellement appeler removeObserver:forKeyPath:
sur cet objet pour le nettoyer ultérieurement. Avant de faire cela, est-il possible de vérifier si un objet observe réellement cette propriété?
J'ai essayé de m'assurer dans mon code qu'un objet est supprimé uniquement par un observateur, mais il est parfois possible que l'observateur puisse essayer de se supprimer deux fois. Je travaille pour empêcher cela, mais juste au cas où, je viens juste d'essayer de savoir s'il existe un moyen de vérifier d'abord si mon code est réellement un observateur de quelque chose.
[...] est-il possible de vérifier si un objet observe réellement cela propriété?
Non. Lorsque vous traitez avec KVO, vous devez toujours garder à l'esprit le modèle suivant:
Lorsque vous établissez une observation, vous êtes responsable de la suppression de cette observation exacte. Une observation est identifiée par son contexte - par conséquent, le contexte doit être unique. Lorsque vous recevez des notifications (et, dans Lion, lorsque vous supprimez l'observateur), vous devez toujours tester le contexte, pas le chemin.
La meilleure pratique pour manipuler les objets observés est de supprimer et d’établir l’observation dans le poseur de l’objet observé:
static int fooObservanceContext;
- (void)setFoo:(Foo *)foo
{
[_foo removeObserver:self forKeyPath:@"bar" context:&fooObservanceContext];
_foo = foo; // or whatever ownership handling is needed.
[foo addObserver:self forKeyPath:@"bar" options:0 context:&fooObservanceContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == &fooObservanceContext) {
// handle change
} else {
// not my observer callback
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc
{
self.foo = nil; // removes observer
}
Lorsque vous utilisez KVO, vous devez vous assurer que les deux objets, observateur et observateur, sont en vie tant que l'observation est en place.
Lorsque vous ajoutez une observation, vous devez équilibrer cela avec exactement une suppression de la même observation. Ne présumez pas que vous êtes le seul à utiliser KVO. Les classes de structure peuvent utiliser KVO à leurs propres fins. Par conséquent, vérifiez toujours le contexte dans le rappel.
Une dernière question que je voudrais signaler: la propriété observée doit être conforme à KVO. Vous ne pouvez rien observer .
Une partie du protocole NSKeyValueObserving est la suivante:
- (void *)observationInfo
qui devrait énumérer les observateurs.
MODIFIER Utile pour le débogage uniquement.
Je sous-estime que c’est une question objectif-c. Mais comme beaucoup de gens utilisent Swift/objective-c ensemble, j'ai donc souligné l'avantage de la nouvelle API Swift4 par rapport aux anciennes versions de KVO:
Si vous modifiez addObserver
plusieurs fois pour KVO, vous obtiendrez la observeValue
pour chaque modification, autant que le nombre actuel de fois que vous vous êtes ajouté comme observateur.
removeObserver
autant de fois que vous avez ajouté.La Swift4 observe
est beaucoup plus intelligente et rapide!
invalidate
de la token
suffit.invalidat
ing avant de commencer à observer ou plusieurs fois que vous avez fait observe
ne provoquera pas de plantageDonc, pour répondre spécifiquement à votre question, si vous utilisez le nouveau KVO Swift4, vous n’avez pas besoin de vous en soucier. Il suffit d'appeler invalidate
et vous êtes bon. Mais si vous utilisez l'ancienne API, reportez-vous à la réponse de Nikolai