2009-01-01 89 views
8

我有一个情况下,子视图发送通知到其父视图。现在我打电话addObserver:viewWillAppear:removeObserver:viewWillDisappear:。但是,我猜这是不正确的,因为viewWillAppear:视图刷新时调用。可能的位置调用addObserver和removeObserver方法

[[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]; 

谢谢。

回答

5

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

更好的解决方案是设置一个标志,说明你已经注册了,或者在init方法中注册。

1

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

+0

但是,当收到内存警告时,viewDidUnload将被调用,但不是dealloc,当导航回到这个viewcontroller时,viewDidLoad会再次被调用,然后,您的通知再次注册。 – ZYiOS 2011-08-22 02:36:36

+1

你说得对。这篇文章很旧,所以忽略它。重要的是平衡注册和取消注册通话。使用viewDidLoad和viewDidUnload,或者viewDidLoad(带有标志)和dealloc,或者使用init和dealloc来注册和取消注册您的通知。请参阅Ben Gottlieb对相关信息的评论。 – Mustafa 2011-08-22 06:16:12

0

本的权利 - 但我发现另一种可能是脆弱的方式。我刚刚发现这一点,因为我永远得到“...被释放,而关键值观察员仍然注册它”

我不知道为什么 - 但是当我在我的init方法addObserver和removeObserver中我的dealloc方法 - 我仍然得到KVO仍然被观察的消息。我跨过并验证了我的removeObserver被正确调用。

我将我的addobserver移到了viewDidLoad方法中,而这似乎工作。

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

但我可以看到潜在的进入低内存事件的情况,viewDidUnload被调用。如果之后我再次点击dealloc(在我再次点击viewDidLoad之前),我会调用removeObserver两次!

所以,我想我会保留在我的viewDidLoad和我的dealloc。

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

相关问题