观察者从未从NSNotificationCenter中删除

5

我正在将一个视图控制器添加为监听UIKeyboardWillShowNotification通知的观察者。

我在我的viewDidLoad中有这段代码:

[[NSNotificationCenter defaultCenter] addObserver:self
                                     selector:@selector(keyboardWillShow:)
                                         name:UIKeyboardWillShowNotification
                                       object:nil];

在我的dealloc方法中:

[[NSNotificationCenter defaultCenter] removeObserver:self];

即使在关闭视图控制器时调用dealloc,观察者也没有被移除。因此,当我第二次打开它时,NSNotificationCenter将尝试通知已释放的旧对象,导致应用程序崩溃。
我在StackOverflow上看到了几个关于这个特定问题的问题,但是没有一个答案适用于我。
我尝试在viewWillDisappearviewDidDisappear中删除观察者,但是仍然出现相同的问题。
我正在使用ARC。

不要在ARC中使用"dealloc"。 - Vaibhav Gautam
4
@Vaibhav 错了。使用dealloc是完全正确的做法,只是在实现中不能调用[super dealloc] - Gabriele Petronella
我遇到了和你一样的问题,但是我找不到合适的解决方案,所以我通过 BOOL isFirstTime; 来解决这个问题,在 keyboardWillShow- (void)keyboardDidHide 时设置为 YES。{ if(!isFirstTime) return;, , , , , , isTxtFieldKeyBoard = NO; isFirstTime = NO;} - iPatel
@GabrielePetronella:感谢您启发我 :) - Vaibhav Gautam
4个回答

1

你尝试过在viewWillDisappear中使用这段代码吗?

- (void)viewWillDisappear:(BOOL)animated 
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

根据您的解释,我不认为问题在于移除观察者。 尝试从另一个视图控制器触发观察者。如果没有触发,您就会知道移除是成功的,并且当您第二次添加观察者时出现了问题。


是的,正如我在问题中提到的那样,我尝试过了。虽然我没有调用super,但这并没有什么区别,因为默认实现什么也不做。我尝试了你在这里建议的方法,先打开视图控制器一次,然后关闭它,再打开一个具有UITextField的不同视图控制器。当键盘出现时,应用程序崩溃,并显示消息*** -[NewTrackerViewController respondsToSelector:]: message sent to deallocated instance 0xc14ac40NewTrackerViewController是一个从未注销为观察者的视图控制器。 - Hesham

0
也许尝试通过指定之前设置的参数name来实现,像这样:

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];

0

看起来观察者被设置了多次。你的控制器是否继承自一个也注册了相同通知的类?这可能会导致控制器实例被注册为观察者超过一次。作为解决方法,请尝试在添加观察者的控制器类中执行以下操作:

// Remove as observer first
[[NSNotificationCenter defaultCenter] removeObserver:self];
                                      name:UIKeyboardWillShowNotification
                                      object:nil];
// Then add
[[NSNotificationCenter defaultCenter] addObserver:self
                                      selector:@selector(keyboardWillShow:)
                                      name:UIKeyboardWillShowNotification
                                      object:nil];

这将确保观察者仅被添加一次。

希望能有所帮助!


0
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"name" object:nil];

这在我这里运行良好


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接