web-dev-qa-db-fra.com

Comment éviter d'ajouter plusieurs observateurs NSNotification?

À l'heure actuelle, l'API ne semble pas fournir un moyen de détecter si un observateur a déjà été ajouté pour une notification NS particulière. Quel est le meilleur moyen d'éviter d'ajouter plusieurs observateurs NSNotification autres que de maintenir un drapeau sur votre extrémité pour assurer le suivi? Quelqu'un a-t-il déjà créé une catégorie pour faciliter cela?

38
Boon

Une façon d'éviter que des observateurs en double ne soient ajoutés consiste à appeler explicitement removeObserver pour la cible/sélecteur avant de l'ajouter à nouveau. J'imagine que vous pouvez ajouter ceci en tant que méthode de catégorie:

@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

Cela suppose que vous n'ajouterez qu'un seul observateur à chaque cible pour tout nom de notification, car cela supprimera tout observateur existant pour ce nom de notification.

68
futureelite7

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)
    }
}
19
dimpiax

La réponse upvoted avec extension NotificationCenter { ... } ne fonctionnait pas pour moi, car mon application créait une nouvelle instance d'un viewController (il y avait un observateur de notification) chaque fois qu'une notification était publiée. Par conséquent, supprimer un observateur sur une nouvelle instance d'un viewController n'a évidemment aucun effet. t fonctionne. Des instances précédentes du viewController auquel des observateurs de notification ont été appelés ont été appelées. 

Les fonctions ci-dessous ont fonctionné pour moi, car cela supprimait Notification Observer dès que la vue disparaissait.

// 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)


}
1
user44776