调用addObserver和removeObserver方法的可能位置

时间:2009-01-01 04:31:56

标签: iphone cocoa notifications addobserver

我遇到子视图向其父视图发送通知的情况。现在我在addObserver:中调用viewWillAppear:,在removeObserver:调用viewWillDisappear:。但是,我猜这是不正确的,因为viewWillAppear:调用视图刷新时。

[[NSNotificationCenter defaultCenter] addObserver: (id)observer selector: (SEL)aSelector name: (NSString *)aName object: (id)anObject];

[[NSNotificationCenter defaultCenter] removeObserver: (id)observer name: (NSString *)aName object: (id)anObject];

感谢。

3 个答案:

答案 0 :(得分:5)

实际上,这是一个坏主意。当内存变低时,视图控制器可能会收到内存警告。此实例中的默认行为是清除视图(如果您当前不在屏幕上)。在这种情况下,您可以第二次发送viewDidLoad消息(在内存事件之后,当您的视图由其导航控制器返回到屏幕上时。)因此,您将对同一对象进行两次注册,但只有一次删除(在其dealloc中)

更好的解决方案是设置一个表示您已注册的标志,或者在您的init方法中注册。

答案 1 :(得分:1)

我想注册通知的正确位置是viewDidLoad方法,并且取消注册相同通知的正确位置是dealloc方法。

答案 2 :(得分:0)

Ben是对的 - 但我找到了另一种可能很脆弱的方式。我刚刚发现了这个,因为我永远得到了“...被解除分配,而关键价值观察者仍在注册”

我不知道为什么 - 但是当我在我的init方法中使用addObserver,并且在我的dealloc方法中使用removeObserver时 - 我仍然得到KVO仍然被观察到的消息。我介入并验证我的removeObserver被正确调用。

我将addobserver移到了viewDidLoad方法中,而这似乎有效。

我在dealloc中的viewDidUnload 中留下了removeObserver;但我不喜欢这样,因为它不平衡。但在正常情况下,我的viewDidUnload不会被调用 - 这只是保护,以防我得到低内存通知。

但我可以看到可能进入低内存事件的情况,调用viewDidUnload。如果我在那之后的某个时间点击dealloc(在我再次点击viewDidLoad之前),我将调用removeObserver两次!

所以,我想我会把它保存在我的viewDidLoad和我的dealloc中。

如果我在init方法中执行addobserver,我仍然不知道为什么它不能正常工作。