1

NSNotificationCenter からオブザーバーを削除する適切な場所に問題があります

// DetailOfSomethingViewController
@implementation DetailOfSomethingViewController

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                          selector:@selector(showMoreDetail:) 
                                          name:SOME_NOTIFICATION_NAME 
                                          object:sender];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)showMoreDetail:(id)sender {
    [self presentViewController:[[MoreDetailViewController alloc] init] animated:NO completion:nil];
}

テストの実行中に、この viewController のインスタンスをナビゲーション スタックからポップし、新しいインスタンスをスタックにプッシュしようとしました。ナビゲーション スタックからポップされたインスタンスの dealloc メソッドがすぐには呼び出されないことがわかりました。

したがって、dealloc が呼び出される前の瞬間に、SOME_NOTIFICATION_NAME がそのソースから送信された場合、ポップされたインスタンスは引き続きリッスンし、showMoreDetail (注: ナビゲーション スタック上のものは正常に動作します) を呼び出して応答し、MoreDetailViewController を表示しようとはしませんが、アプリケーションウィンドウで。したがって、この警告が発生しました。

Warning: Attempt to present <DetailOfSomethingController: 0xac2c3e0> on <MoreDetailViewController: 0xac268f0> whose view is not in the window hierarchy!

ビューコントローラーインスタンスのナビゲーションスタックに存在することを確認できますが、オブザーバーがポップされたときにすぐにオブザーバーを削除する適切な方法はありますか? 削除コードを viewDidDisappear または viewWillDisappear に配置することはできません。これは、スタックの topViewController でなくても、このコントローラーに通知して何かを実行する必要があるためです。

また、別のビューを表示する前にチェックするコードを追加するには、showMoreDetail がプレゼンテーションを行う唯一のメソッドではなく、より類似したメソッドがあるため、このコントローラー内のいくつかの場所に追加する必要があります。

どんな助け、提案も大歓迎です。

よろしく

4

2 に答える 2

1

UINavigationControllershowMoreDetail:topViewControllerプロパティが self と等しいかどうかを確認し、等しい場合のみ続行します。

于 2013-05-03T07:15:40.210 に答える
1

あなたへの私のアドバイスは、viewWillAppear: で viewController をオブザーバーとして登録し、viewWillDisappear: でそれを削除することです。

そうすれば、ビューは最上位のviewControllerの場合にのみ応答します。

アップデート:

あなたができることは、ビューが表示されたときにのみその通知に登録することだと思います:

- (void)viewWillAppear:(BOOL)animated{

    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                          selector:@selector(showMoreDetail:) 
                                          name:SOME_NOTIFICATION_NAME 
                                          object:sender];
}

View Controllerをオブザーバーとして削除する場合も同じです(その通知のためだけに、他の通知を引き続きリッスンします)

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:SOME_NOTIFICATION_NAME
                                                  object:nil]; 

}
于 2013-05-03T06:38:57.260 に答える