web-dev-qa-db-ja.com

複数のNSNotificationオブザーバーの追加を避ける方法は?

現在のところ、APIは、特定のNSNotificationにオブザーバーがすでに追加されているかどうかを検出する方法を提供していないようです。追跡するためにフラグを維持する以外に、複数のNSNotificationオブザーバーを追加しないようにする最善の方法は何ですか?これを容易にするためにすでに誰かがカテゴリを作成していますか?

40
Boon

重複するオブザーバーが追加されるのを防ぐ1つの方法は、ターゲット/セレクターのremoveObserverを明示的に呼び出してから、再度追加することです。これをカテゴリメソッドとして追加できると思います。

@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

これは、通知名の既存のオブザーバーを削除するため、通知名の各ターゲットに一意のオブザーバーを1つだけ追加することを前提としています。

70
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

私のアプリは通知が投稿されるたびにviewController(これには通知オブザーバーがありました)の新しいインスタンスを作成していたため、extension NotificationCenter { ... }での賛成投票は機能しませんでした。 viewControllerは明らかに機能しません。 Notification ObserversがあったviewControllerの以前のインスタンスが呼び出されていました。

ビューが消えると同時に通知オブザーバーが削除されていたため、以下は私にとってはうまくいきました。

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


}
2
user44776