標籤:情境 簡單的 變化 多對多 不用 font 簡單 屬性 刪除
通知:通知中樞實際上是在程式內部提供了訊息廣播的一種機制。通知中樞不能在進程間進行通訊。實際上就是一個二傳手,把接收到的訊息,根據內部的一個訊息轉寄表,來將訊息轉寄給需要的對象。通知中樞是基於觀察者模式的,它允許註冊、刪除觀察者。
一個 NSNotificationCenter 可以有許多的通知訊息 NSNotification, 對於每一個 NSNotification 可以有很多的觀察者 Observer 來接收通知。
委託代理:委託代理(degegate),顧名思義,把某個對象要做的事情委託給別的對象去做。那麼別的對象就是這個對象的代理,代替它來打理要做的事。反映到程式中,首先要明確一個對象的委託方是哪個對象,委託所做的內容是什麼。
委託機制是一種設計模式,在很多語言中都用到的,這隻是通用的思想,網上會有很多關於這方面的介紹。
那麼二者在開發的過程中,到底在什麼情況下用何種方式更為方便和提高效率,根據筆者的開發經驗總結一二,望大家不要見笑,有錯誤的地方,歡迎指正
通知的優勢:通知使用起來非常方便,我們只需要在訊息需要廣播的地方發出去訊息,至於訊息內部怎麼發的,我們不用管,只需要在我們想要得到這個訊息的地方監聽即可,不用管訊息是怎麼到這兒的。其實裡面的原理也不是很複雜,大家有興趣的可以自己研究。
通知的劣勢:如果通知過多,會造成通知的管理複雜,如果管理不好,你會接收到莫名其妙的訊息,而無法追蹤。
代理的優勢:首先,代理的效率要比通知高(個人見解),其實代理就是 c++ 裡面的回調,調用我們都很明白,加上個回可能很多人都感覺迷糊了,其實也是調用,只是在我們直觀的看的時候,感覺好像是我已經做過某件事情了,可是我們還能接收到已經過去一件事情的反饋,其實這個通知差不多,只是我們自己在已經做的事情裡面去預先判斷了某件可能發生的事情,然後主動的告訴我們,我們想要得到的某件事情。
代理的劣勢:實現起來比較複雜,而且應用的情境沒有通知多。
那麼下面我們討論下什麼情況下用代理,什麼情況下用通知 :
如果一個通知的寄件者有多個接受者,而且接受的位置完全不確定,那麼這種情況下用通知是比較好的方式。
如果一個類能夠擷取到通知的對象,這種情況下,我們用代理的效率會更高,而且能夠更好的實現要代理的對象的管理。
代理的應用情境:
n對象A內部發生了一些事情,想通知對象B
n對象B想監聽對象A內部發生了什麼事情
n對象A想在自己的方法內部調用對象 B的某個方法,並且對象 A 不能對對象 B 有耦合依賴
n對象A想傳遞資料給對象 B
以上情況,結果都一樣:對象 B 是 對象 A 的代理 (delegate)
n共同點
利用通知和代理都能完成對象之間的通訊
(比如A對象告訴B對象發生了什麼事情,A 對象傳遞資料給 D 對象)
n不同點
代理:一對一(1個對象只能告訴另1個對象發生了什麼事情)
通知:多對多關係(1個對象能告訴 N 個對象發生了什麼事情,1個對象能得知 N 個對象發生了什麼事情)
KVO
KVO是一個對象能夠觀察另外一個對象的屬性值,並且能夠發現值的變化。kvo更加適合任何類型的對象偵聽另外一個任意對象的改變,或者是一個對象與另外一個對象保持同步的一種方法,即當另外一種對象的狀態發生改變時,觀察對象馬上作出反應。它只能用來對屬性作出反應,而不會用來對方法或者動作作出反應。
kvo的優點 :
1、能夠提供一種簡單的方法實現兩個對象間的同步;
2、能夠對非我們建立的對象,即內部對象的狀態改變作出響應,而且不需要改變內部對象(SDK對象)的實現;
3、能夠獲得觀察的屬性的最新值以及先前值;
4、用 key path 來觀察屬性,因此也可以觀察嵌套對象(也就是可以觀察一個對象內部對象的屬性的變化,可以無限嵌套觀察,前提是對象的屬性支援kvo);
5、完成了對觀察對象的抽象,因為不需要額外的代碼來允許觀察值能夠被觀察(不需要像通知一樣還需要發送通知,kvo 屬性的改變,外部可以直接觀察)。
kvo的注意事項:
我們註冊kvo的時候,要觀察哪個屬性,在調用註冊方法的時候,addObserver: forKey: options: context : forKey 處填寫的屬性是以字串形式,萬一屬性名稱字寫錯,因為是字串,編譯器也不會警告以及檢查
kvo的使用:
被觀察者發出 addObserver : forKey : options : context : 方法來添加觀察者。然後只要被觀察者的 keyPath 的值變化(注意:單純改變其值不會調用此方法,只有通過 getters 和 setters 來改變值才會觸發 kvo),就會在觀察者裡調用 observeValueForKeyPath : ofObject : change : context : 因此觀察者需要實現方法 observeValueForKeyPath : ofObject : change : context ; 來對 kvo 發出的通知作出響應。
這些代碼只需要在觀察者裡進行實現,被觀察者不用添加任何代碼,所以誰要監聽誰註冊,然後對響應進行處理即可,使得觀察者與被觀察者完全解耦,運用很靈活很簡單,但是 kvo 只能檢測類中的屬性,並且屬性名稱都是通過 NSString 來尋找,編譯器不會幫你檢錯和補全,純手敲所以比較容易出錯。
iOS------通知、代理、kvo 詳解