2回呼び出されるNSNotification
のオブザーバーがあります。どうすればいいのかわかりません。
Googleで検索しましたが、解決策が見つかりませんでした。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(connectedToServer:) name:@"ConnectedToServer" object:nil];
- (void)connectedToServer:(NSNotification*)notification {
[[NSNotificationCenter defaultCenter] postNotificationName:@"SendMessageToServer" object:message];
}
解決策1:最初に、通知自体が2回投稿されているかどうかを確認します。
解決策2:通知が1回だけ投稿された場合でも、actionは、追加した回数だけ呼び出されます通知のオブザーバー(通知が同じかどうかに関係なく)。たとえば、次の2行は、同じnotification(self
)のobserver(aSelector
)を2回登録します。
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
オブザーバーを2回目に追加する場所を見つけて、削除する必要があります。また、オブザーバーを追加するコードが2回呼び出されないようにしてください。
解決策3:既にオブザーバーを追加したかどうかわからない場合は、次の手順を実行できます。これにより、オブザーバーが1回だけ追加されるようになります。
[[NSNotificationCenter defaultCenter] removeObserver:self name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
addObserver
メソッドを複数回実行すると、複数のオブザーバーが作成されます。私の問題は、通知を投稿する前に複数回出現するviewWillAppear
にオブザーバーを配置したため、オブザーバーが複数回呼び出されることでした。
EmptyStackの3番目のソリューションは機能しますが、オブザーバーが2回呼び出される理由があります。そのため、同じオブザーバーを削除して追加する代わりに、不要なコード行を防ぐことができます。
私が経験したような単純なエラーを避けるために、あなたのオブザーバーをviewDidLoad
に置くことをお勧めします。
ViewWillDisappearメソッドでObserverを削除してみてください:
-(void)viewWillDisappear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"startAnimating" object:nil]; }
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
にブレークポイントを設定して、複数回呼び出されるかどうかを確認してください。
Swift 2.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)
}
}
このメソッドは次のように呼び出すことができます。
NSNotificationCenter.defaultCenter().setObserver(self, selector: #selector(methodName), name: "name", object: nil)
拡張機能は、前のオブザーバーが存在する場合、その削除を処理します。以前にオブザーバーが存在していなくても、このコードはクラッシュしません。
同じクラスの2つのインスタンスがあり、通知がそのクラスの1つのインスタンスで2回ではなく、2つのインスタンスで2回実行されていることに気付くまでに時間がかかりました。