cocoa - observer - swift nsnotificationcenter example
¿Cómo evitar agregar múltiples NSNotification observador? (3)
La respuesta Upvoted con la extension NotificationCenter { ... }
no me funcionó, ya que mi aplicación creaba una nueva instancia de viewController (esto tenía un observador de notificaciones) cada vez que se publicaba una notificación, por lo que quitaba un observador en una nueva instancia de una vista. El controlador obviamente no funciona. Se llamaron instancias anteriores de ViewController que tenían Notification Observers.
Lo siguiente funcionó para mí, ya que esto eliminaba el Notification Observer tan pronto como la vista se estaba desapareciendo.
// Notification observer added
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(self.someFunc(notification:)), name: Notification.Name("myNotification"), object: nil)
}
// Notification observer removed
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: Notification.Name("myNotification"), object: nil)
}
En este momento, la API no parece proporcionar una forma de detectar si un observador ya ha sido agregado para una NSNotificación en particular. ¿Cuál es la mejor manera de evitar agregar múltiples observadores NSNotification que no sea mantener una bandera en su extremo para realizar un seguimiento? ¿Alguien ha creado una categoría para facilitar esto?
Una forma de evitar que se agreguen observadores duplicados es llamar explícitamente removeObserver para el destino / selector antes de volver a agregarlo. Me imagino que puedes agregar esto como un método de categoría:
@interface NSNotificationCenter (UniqueNotif)
- (void)addUniqueObserver:(id)observer selector:(SEL)selector name:(NSString *)name object:(id)object {
[[NSNotificationCenter defaultCenter] removeObserver:observer name:name object:object];
[[NSNotificationCenter defaultCenter] addObserver:observer selector:selector name:name object:object];
}
@end
Esto supone que solo agregará un observador único a cada objetivo para cualquier nombre de notificación, ya que eliminará cualquier observador existente para ese nombre de notificación.
Swift 3, 4:
import Foundation
extension NotificationCenter {
func setObserver(_ observer: AnyObject, selector: Selector, name: NSNotification.Name, object: AnyObject?) {
NotificationCenter.default.removeObserver(observer, name: name, object: object)
NotificationCenter.default.addObserver(observer, selector: selector, name: name, object: object)
}
}
Swift 2:
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)
}
}