Comment puis-je savoir si un objet a une valeur clé de l'observateur attaché
si vous dites à un objectif c de l'objet à removeObservers: pour un chemin de clé et cette clé n'a pas été enregistré, il les fissures de la dau. comme -
'Impossible de supprimer un observateur pour le chemin d'accès clé "theKeyPath", car il n'est pas enregistré en tant qu'observateur.'
est-il un moyen pour déterminer si un objet a un régime enregistré d'observateur, afin que je puisse faire ce
if (object has observer){
remove observer
}
else{
go on my merry way
}
- Je suis entré dans ce scénario, la mise à jour d'une ancienne application sur iOS 8 d'où une vue contrôleur était libéré et en jetant l' "Impossible de supprimer" l'exception". J'ai pensé que, en appelant
addObserver:
dansviewWillAppear:
et, en conséquence,removeObserver:
dansviewWillDisappear:
, les appels ont été correctement appariés. Je dois faire une solution rapide, je vais donc mettre en œuvre le try-catch solution et laisser un commentaire pour enquêter sur la cause de plus. - Je suis juste de traiter avec quelque chose de similaire et je vois j'ai besoin de regarder dans ma conception de plus en plus profondément et de le régler de sorte que je n'aurez pas besoin de retirer l'observateur de nouveau.
Vous devez vous connecter pour publier un commentaire.
Mettre un try catch autour de votre removeObserver appel
try
portée. clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions Si vous ne considérez pas cela, vous pourriez finir avec les fuites de mémoire et de la mémoire augmente.La vraie question est pourquoi vous ne saurez pas si vous êtes d'observation ou non.
Si vous ne le faites pas dans la classe de l'objet observé, arrêter. Tout en observant qu'il s'attend à garder l'observant. Si vous coupez l'observateur, de notifications à son insu, attendre que les choses se rompre; plus précisément, s'attendre à l'observateur de l'état à rassir comme il ne veut pas recevoir des mises à jour à partir de l'ex-objet observé.
Si vous ne le faites pas dans l'observation de classe d'un objet, il suffit de rappeler les objets dont vous êtes l'observation (ou, si vous ne jamais observer un objet, si vous êtes à l'observation). C'est à supposer que l'observation est dynamique et entre les deux, d'ailleurs sans rapport avec les objets; si l'observateur est propriétaire de l'observer, il suffit d'ajouter l'observateur après vous de créer ou de conserver l'observé, et de supprimer l'observateur avant de relâcher l'observé.
L'ajout et la suppression d'un objet comme un observateur devrait se produisent habituellement dans l'observateur de la classe, et jamais dans l'objet observé est.
viewDidLoad
et supprimer lui-même dansdealloc
. Ne sera pas que crash sidealloc
est appelée avantviewDidLoad
? Je suis sûr que cela ne se produira pas dans mon cas, depuis que je suis tout simplement en poussant la-vue-contrôleur, mais je suppose que nous allons le découvrir! 🙂 Un moyen plus sûr peut-être d'observer dansinit
et gardeobserveValueForKeyPath:ofObject:change:context:
avec[self viewIsLoaded]
, mais c'est probablement superflu dans ce cas. Pensées?deinit
avant votre AVplayer eu la chance d'être arrêté. Il arrive et il est difficile de fixer et de reproduire. Cela aurait pu être évité en ne faisant pas une affaire énorme et/ou en fournissant un moyen sûr pour gérer KVO.FWIW,
[someObject observationInfo]
semble êtrenil
sisomeObject
ne dispose pas de tous les observateurs. Je ne ferais pas confiance à ce problème, cependant, comme je n'en ai pas vu documenté. Aussi, je ne sais pas comment lireobservationInfo
à obtenir des observateurs.objectAtIndex:
n'a pas donné de résultat souhaité).NSKeyValueObserving.h
Lorsque vous ajoutez un observateur à un objet que l'on pourrait ajouter à un
NSMutableArray
comme ceci:Si vous voulez unobserve les objets, vous pouvez faire quelque chose comme:
Rappelez-vous, si vous unobserve un seul objet de la retirer de l'
_observedObjects
tableau:La seule façon de le faire est de définir un indicateur lorsque vous ajoutez un observateur.
À mon avis - ce fonctionne de manière similaire à retainCount mécanisme. Vous ne pouvez pas être sûr qu'à l'heure actuelle, vous avez votre observateur.
Même si vous cochez la case: auto.observationInfo - vous ne pouvez pas savoir pour sûr que vous allez avoir/ne pas avoir des observateurs dans l'avenir.
Comme retainCount. Peut-être que le observationInfo méthode n'est pas exactement le genre de l'inutile, mais je ne l'utilise à des fins de débogage.
Donc, par conséquent, vous avez juste à faire comme dans la gestion de la mémoire. Si vous avez ajouté un observateur - il suffit de l'enlever lorsque vous n'en avez pas besoin. Comme l'utilisation de viewWillAppear/viewWillDisappear etc. des méthodes. E. g:
Et vous avez besoin de quelques vérifications spécifiques - mettre en œuvre votre propre classe qui gère un tableau d'observateurs et de les utiliser pour vos contrôles.
[self removeObserver:nil forKeyPath:@""];
faut aller de l'avant:[super viewWillDisappear:animated];
- (void) setupSomething { [super setupSomething]; … } - (void) tearDownSomething { … [super tearDownSomething]; }
[someObject observationInfo]
retournil
si il n'y a pas d'observateur.Le point de l'ensemble de l'observateur modèle est de permettre à une classe d'être "scellés" -- de ne pas savoir ou de soins qu'il est observé. Vous êtes explicitement essayer de briser cette habitude.
Pourquoi?
Le problème que vous rencontrez est que vous êtes en supposant que vous êtes observé lorsque vous ne l'êtes pas. Cet objet n'a pas de début de l'observation. Si vous souhaitez que votre classe d'avoir le contrôle de ce processus, alors vous devriez envisager d'utiliser le centre de notification. De cette façon, votre classe a le plein contrôle sur quand les données peuvent être observés. Par conséquent, il ne se soucie pas de qui regarde.
Je ne suis pas un fan de cette try catch solution
ce que je fais la plupart du temps, c'est que je créer un vous abonner et vous désabonner de la méthode pour une notification spécifique à l'intérieur de cette classe. Par exemple, ces deux méthodes subcribe ou vous désabonner de l'objet sur le clavier globaux de notification:
À l'intérieur de ces méthodes-je utiliser une propriété privée qui est à true ou false en fonction de l'abonnement de l'état comme suit:
En plus de Adam de la réponse, je voudrais suggérer à l'utilisation de la macro comme ceci
exemple d'utilisation