¿Cómo detener al Observador en NSNotification a llamado dos veces?


Tengo un observador de NSNotification que se llama dos veces. No sé qué hacer con él.

Lo busqué en Google, pero no encontré ninguna solución.

[[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(connectedToServer:) name:@"ConnectedToServer" object:nil];

- (void)connectedToServer:(NSNotification*)notification {

    [[NSNotificationCenter defaultCenter] postNotificationName:@"SendMessageToServer" object:message];
}
Author: Josh Brown, 2011-10-13

5 answers

Solución 1: lo primero es comprobar si la notificación se publica dos veces.

Solución 2: Incluso si la notificación se publica solo una vez, la acción se llamará tantas veces como haya agregado el observador para la notificación (no importa que la notificación sea la misma o no). Por ejemplo, las dos líneas siguientes registrarán dos veces al observador(self) para la misma notificación(aSelector).

[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];

Tienes que encontrar dónde estás agregando observador por segunda vez, y quitarlo. Y también asegúrese de que el código donde se añade el observador no se llama dos veces.

Solución 3: Si no está seguro de si ya ha agregado el observador o no, simplemente puede hacer lo siguiente. Esto asegurará que el observador se agregue solo una vez.

[[NSNotificationCenter defaultCenter] removeObserver:self name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
 122
Author: EmptyStack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-03 10:56:26

Si su método addObserver se ejecuta varias veces, creará varios observadores. Mi problema fue que de alguna manera coloqué a mi observador en viewWillAppear que apareció varias veces antes de publicar la notificación y resultó en que mi observador fuera llamado varias veces.

Mientras la 3ra solución de EmptyStack funciona, hay una razón por la que su observador está siendo llamado dos veces, por lo que al encontrarlo, puede evitar líneas de código innecesarias en lugar de eliminar y agregar el mismo observador.

Me gustaría sugiera poner su observador en viewDidLoad para evitar errores simples como el que experimenté.

 14
Author: tfrank377,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-05 00:16:03

Intenta eliminar el observador en el método viewWillDisappear:

-(void)viewWillDisappear:(BOOL)animated{

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"startAnimating" object:nil]; }
 6
Author: bhadresh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-15 08:29:26

Intente establecer un punto de interrupción en [[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil]; y compruebe si se llama más de una vez.

 2
Author: stcui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-19 09:42:07

Para aquellos que buscan una solución en Swift 2.2 y superior y que han llegado a esta pregunta como yo, puede crear una extensión de la siguiente manera :

import Foundation

extension NSNotificationCenter {
  func setObserver(observer: AnyObject, selector: Selector, name: String?, object: AnyObject?) {
    NSNotificationCenter.defaultCenter().removeObserver(observer, name: name, object: object)
    NSNotificationCenter.defaultCenter().addObserver(observer, selector: selector, name: name, object: object)
  }
}

Puede llamar a este método de la siguiente manera :

NSNotificationCenter.defaultCenter().setObserver(self, selector: #selector(methodName), name: "name", object: nil)

La extensión manejará la eliminación del observador anterior si existe. Incluso si no había ningún observador anterior presente este código no se bloqueará.

 2
Author: Joyson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-01 05:52:11