NSNotificationCenter defaultCenter筆記

蘋果的消息機制是個非常好用的東西,當需要在類的各個實例之間傳遞消息或者寫一些事件驅動的程序時,絕對是個不錯的工具。但是使用時一不小心就會造成引用已經被dealloc的對象的錯誤,引起程序崩潰。於是,在合適的時機addobserver和removeobserver就是個很關鍵的事情。下面,分幾種情況來闡述一下自己的一點想法。


一,使用defaultcenter。

簡單的情況下,若自己沒有太多的消息需要註冊和處理,直接使用[NSNotificationCenter defaultCenter]來調用默認的消息中心就夠用了。如果,有一些特殊的要求那麼,就需要試一下一個繼承自NSnotificationcenter的子類。

二,在視圖顯示的時候接受消息。

有些時候,我們需要在一個已經顯示在主界面上的ViewController上做一點動作,比如當一個同步過程完成後,把同步的結果顯示在界面上。但是,如果這個ViewController沒有顯示在主界面上的話,它就不關心同步結果是什麼樣子了。所以這個時候,我們可以在viewwillappear或者viewdidapper中addobserver添加消息監聽。然後在viewwilldisappear和viewDidDisappear中removeObserver把消息註銷掉。

三,在類的實例存在的時候接受消息。

很多時候,我們需要讓一些類的實例只要在內存中,就要接受消息,處理一些事情。比如我們有一個管理同步的類SyncManager,這個類使用了單例模式,從它alloc init之後就需要一些監聽同步的狀態,並作出處理。這個時候,我們就需要在重寫init函數,在其中註冊消息。
  1. - (id) init
  2. {
  3.     self = [super init];
  4.     if(self)
  5.     {
  6.          [[NSNotificationCenter defaultCenter] addObserver........]
  7.      }
  8.      return self;
  9. }
複製代碼
然後在dealloc中註銷
  1. - (void) dealloc

  2.     ......
  3.     [ [NSNotificationCenter defaultCenter] removeObserver.......]
  4.     [super dealloc]
  5. }
複製代碼
四,在viewController存在的時候接受消息很多時候,我們會與ViewController打交道,甚至有些時候我們希望只要ViewController在內存中就監聽一些消息作出一些動作。剛開始的時候,我想實現這個功能,我是這麼寫的
  1. - (void) viewDidLoad
  2. {
  3.     ......
  4.     [[NSNotificationCenter defaultCenter] addObserver........]
  5.     .....
  6. }
  7. - (void) viewDidUnload

  8.     ......
  9.     [ [NSNotificationCenter defaultCenter] removeObserver.......]
  10.     ......
  11. }
複製代碼
但是,在使用的過程中我發現viewDidLoad和Viewdidunload並不是成對出現的,只有在內存緊張和一些特定的情況下系統纔會調用視圖的ViewDidUnload來卸載視圖。而ViewDIdload每一次加載都會執行。也就是說removeObserver並不一定能夠被執行到,這就留下隱患。當視圖被dealloc之後,還在監聽消息。最終會造成程序的崩潰。而且有些時候如果沒有在unload中removeOberver還會造成多次註冊同一個消息。造成同一個函數執行多次。引起不必要的麻煩。然後,在使用過程中,經過多次試驗我發現,使用init註冊消息並在dealloc註銷消息最爲合適,就像第三條說的那樣。在這裏值得提醒的一點是蘋果的官方文檔上說:
  1. The notification center does not retain its observers, therefore, you must ensure that you unregister observers (using removeObserver: or removeObserver:name:object:) before they are deallocated. (If you don't, you will generate a runtime error if the center sends a message to a freed object.)
複製代碼

意思是NotificationCenter並不會對Observer進行retain操作。因爲就沒有必要對observer做多餘的release操作,而且,每一次註冊,必須對應一次註銷,不然,程序死翹翹的事情就會來了。


實際使用過程中,需要非常注意的是:addObserver........和removeObserver.......兩個方法要成對出現,在某個地方添加了觀察者,就要在某個安全的地方remove掉,不然會造成觀察者方法重複調用,即使程序沒有崩潰,也會出現很多不確定現象,也不容易發現問題所在。這個是在實際項目中反覆調試才發現的,所以記錄下來,其實最好還是把蘋果的開發文檔都通讀一遍,這些問題就能避免,但是看文檔的時間成本太高,所以發現一個問題,就及時記錄下來,避免以後再出類似問題。



轉自:http://bbs.9ria.com/thread-226523-1-1.html

原文地址:http://www.1000phone.net/thread-8617-1-1.html
發佈了7 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章