2009-01-01 57 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。

相關問題