使用 NSNotification 删除观察者...我做错了什么?

发布于 2024-09-10 23:17:50 字数 1404 浏览 6 评论 0原文

基本上,我有一个 view1,它在某个时候调用 view2 (通过 PresentModalViewController:animated: )。当按下 view2 中的某个 UIButton 时,view2 会调用 view1 中的通知方法,然后立即关闭。通知方法弹出警报。

通知方法工作正常并且被适当地调用。问题是,每次创建 view1 时(一次只能存在一个 view1),我可能会创建另一个 NSNotification ,因为如果我从 view0 (菜单)转到 view1,然后返回并创建连续几次,我从通知方法中收到一系列相同的警报消息,一次又一次,与我打开 view1 的次数一样多。

这是我的代码,请告诉我我做错了什么:

View1.m

-(void) viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(showAlert:) 
                                                 name:@"alert" 
                                               object:nil];
}

-(void) showAlert:(NSNotification*)notification {
    // (I've also tried to swap the removeObserver method from dealloc
    // to here, but it still fails to remove the observer.)
    // < UIAlertView code to pop up a message here. >
}

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

View2.m

-(IBAction) buttonWasTapped {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"alert" 
                                                        object:nil];
    [self dismissModalViewControllerAnimated:YES];
}

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

Basically, I have a view1 which at some point, calls view2 (via presentModalViewController:animated:). When a certain UIButton in view2 is pressed, view2 is calls a notification method in view1 and immediately afterward is dismissed. The notification method pops up an alert.

The notification method works fine and is called appropriately. The problem is, every time view1 is created (only one view1 should exist at a time), I presumably get another NSNotification being created because if I go from view0 (the menu) to view1, then back and forth a few times, I get a series of the same alert message, one after another, from the notification method as many times as I opened a view1.

Here is my code, please tell me what I'm doing wrong:

View1.m

-(void) viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(showAlert:) 
                                                 name:@"alert" 
                                               object:nil];
}

-(void) showAlert:(NSNotification*)notification {
    // (I've also tried to swap the removeObserver method from dealloc
    // to here, but it still fails to remove the observer.)
    // < UIAlertView code to pop up a message here. >
}

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

View2.m

-(IBAction) buttonWasTapped {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"alert" 
                                                        object:nil];
    [self dismissModalViewControllerAnimated:YES];
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梨涡少年 2024-09-17 23:17:50

视图控制器关闭后,调用 -dealloc 不会自动发生 - 视图控制器的生命周期中仍然可能存在一些“生命”。在该时间范围内,该视图控制器仍然订阅该通知。

如果您在 -viewWillDisappear:-viewDidDisappear: 中删除观察者,这将产生更直接的效果:

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

Calling -dealloc doesn't automatically happen after the view controller is dismissed — there can still be some "life" left in the view controller's lifetime. In that timeframe, that view controller is still subscribed for that notification.

If you remove the observer in -viewWillDisappear: or -viewDidDisappear:, this will have a more immediate effect:

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                    name:@"alert" 
                                                  object:nil];
}
最美不过初阳 2024-09-17 23:17:50

如果您在 viewWillDisappear:viewDidDisappear: 中实现了观察者的删除,那么您不应该在 viewDidLoad 中保留观察者的添加。

而是将观察者的添加放在 viewWillAppear: 中。您遇到的问题是因为当任何视图显示在 UIViewController 视图上时,您的观察者将会被删除,并且由于您在 viewDidLoad 中添加了观察者,这只会发生一次,就会丢失。

请记住,当您的主视图不在最前面时,这种方法非常适合您不希望观察的对象。

另请记住,viewDidUnload 也已被折旧。

If you implement the removal of Observer in the viewWillDisappear: or viewDidDisappear: then you should not leave the addition of the observer in the viewDidLoad.

Instead put the addition of the observer in the viewWillAppear:. The problem you are having is because when any view is shown onto of the UIViewController view the removal of your observer will occur and since you added observer in viewDidLoad which will happen only once, it will be lost.

Keep in mind that this approach works well for objects you do not wish to observer while your main view is not in the fore front.

Also Keep in mind that viewDidUnload has been depreciated too.

甜警司 2024-09-17 23:17:50

removeObserver: 放入 dealloc 中没有任何问题。事实上它没有被调用意味着 view1 在关闭后没有正确释放。看起来有些东西保存着指向你的 view1 的指针,检查保留周期。

另外,你不应该在 super 上调用 dealloc。

There is nothing wrong putting removeObserver: in dealloc. Just the fact it's not called means view1 not properly releases after dismissing. Looks like something holds pointer to your view1, check for retain cycles.

Also, you shouldn't call dealloc on super.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文