43

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

4

5 に答える 5

72

オブザーバーが重複して追加されるのを防ぐ方法の 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 つだけ追加することを前提としています。

于 2011-04-14T07:51:00.447 に答える
19

スイフト5:

import Foundation

extension NotificationCenter {
  func setObserver(_ observer: Any, selector: Selector, name: Notification.Name, object: Any?) {
    removeObserver(observer, name: name, object: object)
    addObserver(observer, selector: selector, name: name, object: object)
  }
}

スウィフト 3-4:

import Foundation

extension NotificationCenter {
  func setObserver(_ observer: AnyObject, selector: Selector, name: NSNotification.Name, object: AnyObject?) {
    removeObserver(observer, name: name, object: object)
    addObserver(observer, selector: selector, name: name, object: object)
  }
}

スウィフト 2:

import Foundation

extension NSNotificationCenter {
  func setObserver(observer: AnyObject, selector: Selector, name: String?, object: AnyObject?) {
    removeObserver(observer, name: name, object: object)
    addObserver(observer, selector: selector, name: name, object: object)
  }
}
于 2015-03-17T12:26:47.843 に答える
5

extension NotificationCenter { ... }通知が投稿されるたびにアプリがviewControllerの新しいインスタンス(これには通知オブザーバーがありました)を作成していたため、Upvotedの回答はうまくいきませんでした。仕事。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)


}
于 2017-09-27T12:33:40.843 に答える