1、觀察者(Observer)模式也叫發布/訂閱(Publish/Subscribe)模式,是MVC(模型-視圖-控制器)模式的重要組成部分。在軟件系統中,一個對象狀態改變也會連帶影響其他很多對象的狀態發生改變。能夠實現這一需求且復用性強,對象之間匿名通信的,觀察者模式是其中最適合的一個。
2、觀察者模式的類圖如下:
它有四個角色:
抽象主題(Subject):在Objective-C中,抽象主題是一個協議,它是觀察者集合容器,定義了添加觀察者(attach)方法、移除觀察者(detach)方法和為所有觀察者發送通知的方法(notifyObserver)。
抽象觀察者(Observer):在OC中,抽象觀察者是一個協議,它是一個更新(update)方法。
具體觀察者(ConcreteObserver):Observer協議的具體實現。
具體主題(ConcreteSubject):Subject協議的具體實現。
引入Subject和Observer這兩個協議后,不僅提高了系統的可復用性,還降低了耦合度。
抽象觀察者(Observer)和抽象主題(Subject)的實現代碼如下:
1 // 2 //Observer.h 3 //ObserverPattern 4 // 5 @PRotocol Observer 6 @required
-(void)update; 7 @end 8 9 //10 //Subject.h11 //ObserverPattern12 //13 @class Observer;14 @protocol Subject15 @required16 -(void)attach:(Observer*) observer; 17 -(void)detach:(Observer*) observer; 18 -(void)notifyObservers;19 @end
具體觀察者(ConcreteObserver)的實現代碼如下:
////ConcreteObserver.h//ObserverPattern//#import "Observer.h"@interface ConcreteObserver : NSObject <Observer> @end////ConcreteObserver.m//ObserverPattern//#import "ConcreteObserver.h"@implementation ConcreteObserver//只是做了個輸出處理-(void)update{ NSLog(@"ConcreteObserver : %@",self); }@end
下面是具體主題(ConcreteSubject)的實現代碼:
////ConcreteSubject.h//ObserverPattern//#import "Subject.h"@class Observer;@interface ConcreteSubject : NSObject <Subject>{ NSMutableArray* observers;}@property (nonatomic ,strong) NSMutableArray* observers;+(ConcreteSubject*)sharedConcreteSubject;@end////ConcreteSubject.m //ObserverPattern//#import "ConcreteSubject.h" @implementation ConcreteSubject@synthesize observers;static ConcreteSubject *sharedConcreteSubject = nil;+(ConcreteSubject*)sharedConcreteSubject{ static dispatch_once_t once; dispatch_once(&once, ^{ sharedConcreteSubject = [[self alloc] init]; sharedConcreteSubject.observers = [[NSMutableArray alloc] init]; }); return sharedConcreteSubject;}-(void)attach:(Observer*) observer{ [self.observers addObject:observer];}-(void)detach:(Observer*) observer{ [self.observers removeObject:observer];}-(void)notifyObservers{ for (id obs in self.observers) { [obs update]; }} @end
因為ConcreteSubject只需要一個實例,所以我們采用單例設計模式實現。
3、通知機制和KVPO機制
在Cocoa Touch框架中,觀察者模式的具體應用有兩個-通知(notification)機制和KVO(Key-Value-Observing)機制。
3.1、通知機制
通知機制和委托機制不同的是,前者是“一對多”的對象之間的通信,后者是“一對一”的對象之間的通信。
如圖,在通知機制中對某個通知感興趣的所有對象都可以成為接收者。首先,這些對象需要向通知中心(NSNotificationCenter)發出addObserver:selector:name:object:消息進行注冊,在投送對象投送通知給通知中心時,通知中心就會把通知廣播給注冊過的接收者。所有的接收者都不知道通知是誰投送的,更不關系它的細節。投送對象與接收者是一對多的關系。接收者如果對通知不再關注,會給通知中心發出removeObserver:name:object:消息接觸注冊,以后不再接收通知。
代碼示例:主界面控制器MainViewController和翻轉界面控制器FilpsideViewController,此外還有應用程序委托對象AppDelegate。我們將兩個視圖控制器座位通知的接收者,應用程序委托對象作為通知投送對象。
在MainViewController和FilpsideViewController這兩個視圖控制器中,注冊通知接收者的代碼如下:
1 - (void)viewDidLoad2 {3 [super viewDidLoad];4 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleTerminate:) name:@"AppWillTerminateNotification" object:nil];5 ?????????????}
解除注冊代碼類似,通過NSNotificationCenter發出removeObserver消息實現。對于一般的OC對象可以在dealloc方法中發出消息。對于視圖控制器,也可以在didReceiveMemoryWarning方法或viewDidUnload方法中發出消息。
1 - (void)dealloc2 {3 [[NSNotificationCenter defaultCenter] removeObserver:self];4 }
MainViewController和FilpsideViewController處理通知的方法基本相同
1 #pragma mark -
新聞熱點
疑難解答