一、定義
觀察者模式定義了對(duì)象之間的一對(duì)多依賴,這樣一來,當(dāng)一個(gè)對(duì)象改變狀態(tài)時(shí),它所有的依賴者都會(huì)收到通知并自動(dòng)更新。
觀察者提供了一種對(duì)象設(shè)計(jì),讓主題和觀察者之間松耦合。
二、使用場(chǎng)景
1、當(dāng)一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴于另一方面。將這二者封裝在獨(dú)立的對(duì)象中以使它們可以各自獨(dú)立地改變和復(fù)用。
2、當(dāng)對(duì)一個(gè)對(duì)象的改變需要同時(shí)改變其他對(duì)象,而不知道具體有多少對(duì)象需要被改變。
3、當(dāng)一個(gè)對(duì)象必須通知其他對(duì)象,而它又不能假定其他對(duì)象是誰。換言之,不希望這些對(duì)象是緊密耦合的
三、簡(jiǎn)單實(shí)現(xiàn)
Cocoa通過兩種方式實(shí)現(xiàn)了這種設(shè)計(jì)模式:通知和KVO(Key-Value Observing)
通知:一對(duì)多
-
添加訂閱者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(doSomething) name:@"notificationName" object:nil];
2.發(fā)布者發(fā)布通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"notificationName" object:nil];
3.移除訂閱
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"notificationName" object:nil];
4.更新UI
- (void) doSomething {
// TODO
}
KVO:一對(duì)一
- 通過
addObserver:forKeyPath:options:context:方法注冊(cè)觀察者,觀察者可以接收keyPath屬性的變化事件。 - 在觀察者中實(shí)現(xiàn)
observeValueForKeyPath:ofObject:change:context:方法,當(dāng)keyPath屬性發(fā)生改變后,KVO會(huì)回調(diào)這個(gè)方法來通知觀察者。 - 當(dāng)觀察者不需要監(jiān)聽時(shí),可以調(diào)用
removeObserver:forKeyPath:方法將KVO移除。需要注意的是,調(diào)用removeObserver需要在觀察者消失之前,否則會(huì)導(dǎo)致Crash。
四、總結(jié)
觀察者模式的主要的作用就是對(duì)對(duì)象解耦,將觀察者和被觀察者完全隔離。
- 觀察者模式的優(yōu)點(diǎn):
觀察者模式解除了主題和具體觀察者的耦合,讓耦合的雙方都依賴于抽象,而不是依賴具體。 - 觀察者模式的缺點(diǎn)
程序中包括一個(gè)被觀察者和多個(gè)被觀察者,開發(fā)和調(diào)試比較復(fù)雜,容易造成客戶端的內(nèi)存泄漏。