28

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

通知方法工作正常并且被适当地调用。问题是,每次创建 view1(一次只应该存在一个 view1)时,我大概会NSNotification创建另一个,因为如果我从 view0(菜单)转到 view1,然后来回几次,我会得到一个一系列相同的警报信息,一个接一个,来自通知方法的次数与我打开视图的次数一样多。

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

查看1.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];
}
4

3 回答 3

61

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

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

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                                                    name:@"alert" 
                                                  object:nil];
}
于 2010-07-25T06:04:54.257 回答
6

如果你在viewWillDisappear:or中实现了 Observer 的移除,viewDidDisappear:那么你不应该在viewDidLoad.

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

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

另外请记住,它viewDidUnload也已贬值。

于 2013-06-19T17:02:30.027 回答
2

removeObserver:放进去没有错dealloc。只是它没有被调用的事实意味着 view1 在解雇后没有正确释放。看起来有些东西持有指向您的 view1 的指针,请检查保留周期。

此外,您不应该在 super 上调用 dealloc。

于 2014-01-24T21:36:50.167 回答