8

我有一个子视图向其父视图发送通知的情况。现在我打电话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];

谢谢。

4

3 回答 3

5

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

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

于 2009-01-01T13:13:09.183 回答
1

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

于 2009-01-01T08:31:39.390 回答
0

本是对的——但我发现了另一种可能很脆弱的方法。我刚刚发现了这一点,因为我永远得到“......在关键值观察者仍在注册时被释放”

我不知道为什么 - 但是当我在我的 init 方法中有 addObserver 和在我的 dealloc 方法中有 removeObserver 时 - 我仍然收到 KVO 仍在被观察消息。我逐步检查并确认我的 removeObserver 被正确调用。

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

我在 viewDidUnloaddealloc 中留下了一个 removeObserver;但我不喜欢这样,因为它不平衡。但在正常情况下,我的 viewDidUnload 不会被调用——这只是为了防止我收到内存不足的通知。

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

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

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

于 2012-03-02T20:44:37.347 回答