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

我给你的建议是在viewWillAppear:中将你的 viewController 注册为观察者, 并在 viewWillDisappear 中删除它

这样你的视图只会在它是顶部视图控制器时响应。

更新:

我认为您可以做的是仅在视图出现时注册该通知:

- (void)viewWillAppear:(BOOL)animated{

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

并且将您的视图控制器作为观察者执行相同的操作(仅针对该通知,它仍会侦听其他通知)

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

}
于 2013-05-03T06:38:57.260 回答
1

showMoreDetail:检查 UINavigationController 的属性是否等于 self,如果等于,topViewController则继续。

于 2013-05-03T07:15:40.210 回答