我遇到子视图向其父视图发送通知的情况。现在我在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];
感谢。
答案 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,我仍然不知道为什么它不能正常工作。