IOS 5 ARCベースのプロジェクトがあり、NSNotificationCenter
内に登録したUIViewController
オブザベーションのオブザーバーを削除する場所について問題があります。 SO)に関する同様の投稿では、これは-dealloc
メソッドで実行する必要があると述べています。このメソッドはARCプロジェクトでは必須ではありませんが、次のコードで追加しました。
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
テストとして、UIViewController
(UINavigationController
内)を開き、通知をトリガーするいくつかの操作を行ってから、[戻る]ボタンをタップしてスタックからポップします。次に、UIViewController
を再度開き、通知をトリガーするためにさらにいくつかのことを行いますが、各コールバックが2回呼び出されていることに注意してください。これは、前の通知が登録解除されていないことを示しています。この手順を繰り返すと、各コールバックが複数回呼び出されるため、登録が解除されることはないように見えます。
どんな助けでもいただければ幸いです!
dealloc
メソッドが呼び出されていないことは明らかです(removeObserver
呼び出しも呼び出されていません)。
viewDidUnload:
またはviewWillDisappear:
メソッドでUIViewControllerのオブザーバーを削除してみませんか?
Deallocが呼び出されていない場合は、誰かがまだViewControllerへの参照を保持していることが原因である可能性があります。おそらく、何かを__weak
としてマークする必要がありますか?割り当てインスツルメントを使用して、ViewControllerに保持されているものを追跡するのに役立てることができます。
「ビューが画面外にある場合でも通知コールバックを起動する必要があります」-> UIApplicationWillEnterForegroundNotificationを登録する必要がある場合があります。もしそうなら、これを試してみましょう:
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"viewWillAppear");
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
NSLog(@"viewWillDisappear");
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"applicationWillEnterForeground");
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
// do your stuff here
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"applicationDidEnterBackground");
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification
object:nil];
}
アイデアは、画面に出入りするたびにUIApplicationDidEnterBackgroundNotificationを追加または削除することです。アプリがバックグラウンドに入るときにUIApplicationWillEnterForegroundNotificationを登録し、戻ったら削除するだけです。 viewWillDisappearの場合、UIApplicationDidEnterBackgroundNotificationを削除するだけであることに注意してください。
私のdealloc()はどういうわけか呼び出されていないので、この方法を見つけました。あなたにも役立つことを願っています。
楽しい :)