si le dice a un objeto c objetivo que elimine los observadores: para una ruta clave y esa ruta clave no se ha registrado, se quiebran los tristes. me gusta -
"No se puede eliminar un observador para la ruta de acceso clave" theKeyPath "porque no está registrado como observador".
¿Hay alguna manera de determinar si un objeto tiene un observador registrado, por lo que puedo hacer esto
if (object has observer){
remove observer
}
else{
go on my merry way
}
objective-c
cocoa
key
key-value-observing
Aran Mulholland
fuente
fuente
addObserver:
enviewWillAppear:
y correspondientementeremoveObserver:
enviewWillDisappear:
las llamadas fueron emparejados correctamente. Tengo que hacer una solución rápida, así que voy a implementar la solución try-catch y dejar un comentario para investigar más a fondo la causa.Respuestas:
Intente atrapar su llamada removeObserver
fuente
La verdadera pregunta es por qué no sabes si lo estás observando o no.
Si está haciendo esto en la clase del objeto que se está observando, deténgase. Lo que sea que esté observando espera seguir observándolo. Si corta las notificaciones del observador sin su conocimiento, espere que las cosas se rompan; más específicamente, espere que el estado del observador se vuelva obsoleto ya que no recibe actualizaciones del objeto observado anteriormente.
Si está haciendo esto en la clase del objeto de observación, simplemente recuerde qué objetos está observando (o, si solo observa un objeto, ya sea que lo esté observando). Esto supone que la observación es dinámica y entre dos objetos que de otro modo no estarían relacionados; si el observador posee lo observado, simplemente agregue el observador después de crear o retener lo observado, y elimine el observador antes de liberar lo observado.
Agregar y eliminar un objeto como observador generalmente debería ocurrir en la clase del observador, y nunca en la del objeto observado.
fuente
FWIW,
[someObject observationInfo]
parece sernil
sisomeObject
no tiene observadores. Sin embargo, no confiaría en este comportamiento, ya que no lo he visto documentado. Además, no sé leerobservationInfo
para obtener observadores específicos.fuente
objectAtIndex:
no produce el resultado deseado.)NSKeyValueObserving.h
La única forma de hacer esto es establecer una bandera cuando agrega un observador.
fuente
Cuando agrega un observador a un objeto, puede agregarlo a algo
NSMutableArray
así:Si desea no observar los objetos, puede hacer algo como:
Recuerde, si no observa un solo objeto, retírelo de la
_observedObjects
matriz:fuente
NSHashTable
/NSMapTable
para mantener las referencias débiles.En mi opinión, esto funciona de manera similar al mecanismo retenerCount. No puede estar seguro de que en el momento actual tenga su observador. Incluso si marca : self.observationInfo : no puede estar seguro de que tendrá / no tendrá observadores en el futuro.
Como retenerCount . Quizás el método observaciónInfo no es exactamente ese tipo de inútil, pero solo lo uso con fines de depuración.
Como resultado, solo tiene que hacerlo como en la administración de memoria. Si agregó un observador, simplemente retírelo cuando no lo necesite. Como usar los métodos viewWillAppear / viewWillDisappear, etc. P.ej:
Y necesita algunas comprobaciones específicas: implemente su propia clase que maneja una variedad de observadores y úsela para sus comprobaciones.
fuente
[self removeObserver:nil forKeyPath:@""];
necesita ir antes:[super viewWillDisappear:animated];
- (void) setupSomething { [super setupSomething]; … } - (void) tearDownSomething { … [super tearDownSomething]; }
[someObject observationInfo]
regresarnil
si no hay observador.fuente
El objetivo del patrón de observador es permitir que una clase observada se "selle", para no saber o importar si se está observando. Está intentando explícitamente romper este patrón.
¿Por qué?
El problema que tienes es que estás asumiendo que te están observando cuando no lo estás. Este objeto no inició la observación. Si desea que su clase tenga control de este proceso, entonces debería considerar usar el centro de notificaciones. De esa manera, su clase tiene control total sobre cuándo se pueden observar los datos. Por lo tanto, no le importa quién está mirando.
fuente
No soy fanático de esa solución try catch, así que lo que hago la mayor parte del tiempo es crear un método de suscripción y cancelación de suscripción para una notificación específica dentro de esa clase. Por ejemplo, estos dos métodos suscriben o anulan la suscripción del objeto a la notificación global del teclado:
Dentro de esos métodos, uso una propiedad privada que se establece en verdadero o falso según el estado de suscripción de la siguiente manera:
fuente
Además de la respuesta de Adam, me gustaría sugerir usar macro como esta
ejemplo de uso
fuente