Qu'est-ce qui ne va pas avec observerValueForKeyPath: ofObject: change: context: implementation?
Dans mon UIScrollView sous-classe, je suis en observant cadre des changements:
[self addObserver:self forKeyPath:@"frame" options:0 context:NULL];
Mon observeValueForKeyPath:ofObject:change:context:
mise en œuvre est comme suit:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == self && [keyPath isEqualToString:@"frame"]) {
[self adjustSizeAndScale];
}
if ([UIScrollView instancesRespondToSelector:@selector(observeValueForKeyPath:ofObject:change:context:)]) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; //Exception
}
}
Mais j'obtiens une exception avec ce code:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<WLImageScrollView: 0x733a440; baseClass = UIScrollView; frame = (0 0; 320 416); clipsToBounds = YES; layer = <CALayer: 0x7346500>; contentOffset: {0, 0}>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: frame
Observed object: <WLImageScrollView: 0x733a440; baseClass = UIScrollView; frame = (0 0; 320 416); clipsToBounds = YES; layer = <CALayer: 0x7346500>; contentOffset: {0, 0}>
Change: {
kind = 1;
}
Context: 0x0'
Signifie-t-il UIScrollView implémente observeValueForKeyPath:ofObject:change:context:
mais jette l'exception ci-dessus?
Si oui, comment puis-je mettre en œuvre correctement observeValueForKeyPath:ofObject:change:context:
de sorte que je peux gérer mon intéressés changements et de donner de la superclasse une chance de traiter ses intéressées changements?
source d'informationauteur an0
Vous devez vous connecter pour publier un commentaire.
Edit: BJ Homère réponse est probablement la meilleure approche à prendre ici; j'ai tout oublié le paramètre de contexte!
Même si l'appel de la super mise en œuvre est par-le-livre, il semble comme appel
observeValueForKeyPath:ofObject:change:context:
surUIKit
classes qui ne sont pas réellement observer les champs en question déclenche uneNSInternalInconsistency
exception (pas leNSInvalidArgumentException
vous obtiendriez avec une inconnue sélecteur). La chaîne de clé dans l'exception qui suggère que pour moi, c'est "reçu, mais ce n'est pas manipulé".Autant que je sache, il n'y a pas bien documenté pour savoir si un objet observe un autre objet sur un chemin de clé. Il peut être partiellement documentée des moyens tels que la
-observationInfo
bien ce qui est dit de transmettre de l'information sur les observateurs d'un objet, mais vous êtes sur votre propre, il y avoid *
.Donc, comme je le vois, vous avez deux options: soit de ne pas appeler le
super
mise en œuvre ou l'utilisation d'un@try
/@catch
/@finally
bloc d'ignorer ce type spécifique deNSInternalInconsistencyException
. La deuxième option est probablement plus à l'avenir mais j'ai un pressentiment qu'un travail de détective pourrait vous obtenir des résultats plus satisfaisants par la première option.Vous devez ajouter un
context
valeur lorsque vous ajoutez l'observateur. Dans votre-observeValueForKeyPath
méthode, vérifiez le paramètre de contexte. Si ce n'est pas le contexte que vous avez passé lorsque vous avez ajouté l'observateur, alors vous savez ce message n'est pas prévu pour votre sous-classe, et vous pouvez les transmettre à la super-classe. Si il est la même valeur, alors vous savez que c'est prévu pour vous, et vous ne devriez pas passer sur le super.Comme ceci: