在軟件開發中,無論哪種高級語言,總會有一些最常用的設計模式。即使iOS開發已經對我們進行了最多的處理,它也只是單例模式、觀察者模式和工廠模式。現在就跟著武林技術頻道的步伐來了解iOS應用開發中使用設計模式中的觀察者模式的實例吧!
觀察者模式本質上時一種發布-訂閱模型,用以消除具有不同行為的對象之間的耦合,通過這一模式,不同對象可以協同工作,同時它們也可以被復用于其他地方Observer從Subject訂閱通知,ConcreteObserver實現重現ObServer并將其重載其update方法。一旦SubJect的實例需要通知Observer任何新的變更,Subject會發送update消息來通知存儲在其內部類中所注冊的Observer、在ConcreteObserver的update方法的實際實現中,Subject的內部狀態可被取得并進行后續處理。其類圖如下:

?
由上面我們可以發現觀察者模式無非在是定義對象間的一種一對多的依賴關系,并且當一個對象的狀態發生改變的時候,所有依賴于它的對象都會得到通知且自動更新。即如果Subject允許其他觀察者(實現了觀察者接口的對象)對這個Subject的改變進行請閱,當Subject發送了變化,那么Subject會將這個變化發送給所有的觀察者,觀察者就能對Subject的變化做出更新。其時序圖如下

通過上面的觀察我們可以發現如果用N個Observer來拓展Subject的行為,這些Observer具有處理存儲在Subject中的信息的特定實現,這樣也就實現了前面所說的消除不同對象間的耦合的功能了。
那么了解了這些我們可能就會更像了解下我們在什么時候才會去使用觀察者模式呢?
?當需要將改變通知所有的對象時,而你又不知道這些對象的具體類型
?改變發生在同一個對象中,并需要改變其他對象將相關的狀態進行更新且不知道有多少個對象。
而同樣的在我們日常的開發中在Cocoa Touch框架中的的兩種經常打交道的技術KVO與通知都實現了觀察者模式,所以下面我們討論的重點也就是基于這兩個方面的。
通知
言歸正傳,在Cocoa Touch框架中NSNotificationCenter和NSNotification對象實現了一對多的模型。通過NSNotificationCenter可以讓對象之間進行通訊,即便這些對象之間并不認識。下面我們來看下NSNotificationCenter發布消息的方法:
?
?? NSNotification? * subjectMessage = [ NSNotification? notificationWithName:@"subjectMessage"? object: self];
??? NSNotificationCenter? * notificationCenter = [ NSNotificationCenter? defaultCenter];
??? [notificationCenter postNotification:subjectMessage];
通過上面的代碼我們創建了一個名為subjectMessage的NSNotification對象,然后通過notificationCenter來發布這個消息。通過向NSNotificationCenter類發送defaulCenter消息,可以得到NSNotificationCenter實例的引用。每個進程中只有一個默認的通知中心,所以默認的NSNotificationCenter是個單例對象。如果有其他觀察者定于了其對象的相關事件則可以通過以下的方法來進行操作:
?
?
?
??? NSNotificationCenter? * notificationCenter1 = [ NSNotificationCenter? defaultCenter];
??? [notificationCenter addObserver: self? selector: @selector(update:) name:@"subjectMessage"? object: nil ];
經過以上步驟我們已經向通知中心注冊了一個事件并且通過selector制定了一個方法update:下面我們可以實現以下這個方法
?
?
?
- (void)update:(NSNotification*)notification{
?
??????? if ([[notification name] isEqualToString:@"subjectMessage"]) {
??????????? NSLog(@"%@",@"猴子派來的救兵去哪了?");
??????? }
}
當然最后如果我們需要對監聽進行銷毀
?
?
?
- (void)dealloc {
??? [[NSNotificationCenter defaultCenter] removeObserver:self];
}
?
實例
抽象主題協議:
?
#import <Foundation/Foundation.h>?
@class Observer;?
?
/*!
?*? 抽象主題協議
?*
?*? @since V1.0
?*/?
@protocol Subject <NSObject>?
?
@required?
?
/*!
?*? 增加觀察者
?*
?*? @param observer 觀察者實例
?*
?*? @since V1.0
?*/?
-(void)attach:(Observer*) observer;?
/*!
?*? 移除觀察者
?*
?*? @param observer 觀察者實例
?*
?*? @since V1.0
?*/?
-(void)detach:(Observer*) observer;?
/*!
?*? 為觀察者發送通知
?*
?*? @since V1.0
?*/?
-(void)notifyObservers;?
?
@end?
觀察者協議:
?
?
?
#import <Foundation/Foundation.h>?
?
/*!
?*? 觀察者協議
?*
?*? @since V1.0
?*/?
@protocol Observer <NSObject>?
?
@required?
-(void)update;?
?
@end?
具體的觀察者類:
?
?
?
#import <Foundation/Foundation.h>?
#import "Observer.h"?
?
/*!
?*? 具體的觀察者類
?*
?*? @since V1.0
?*/?
?
@interface ConcreteObserver : NSObject<Observer>?
?
@end?
具體主題類:
?
?
?
#import <Foundation/Foundation.h>?
#import "Subject.h"?
?
/*!
?*? 具體主題類
?*
?*? @since V1.0
?*/?
@interface ConcreteSubject : NSObject<Subject>?
{?
??? NSMutableArray *observers;?
}?
@property(nonatomic,strong)NSMutableArray* observers;?
/*!
?*? 單例構建自身對象
?*
?*? @return 自身對象
?*
?*? @since V1.0
?*/?
+(ConcreteSubject*)shareConcreteSubject;?
?
@end?
?
了解過通知之后我們來看一下KVO
KVO是Cocoa提供的一種稱為鍵值觀察的機制,對象可以通過它得到其他對象特定屬性的變更通知。而這個機制是基于NSKeyValueObserving非正式些,Cocoa通過這個協議為所有遵循協議的對象提供了一種自動化的屬性監聽的功能。
雖然通知和KVO都可以對觀察者進行實現,但是他們之間還是略有不同的,由上面的例子我們可以看出通知是由一個中心對象為所有觀察者提供變更通知,主要是廣義上關注程序事件,而KVO則是被觀察的對象直接想觀察者發送通知,主要是綁定于特定對象屬性的值。下面我們通過一個簡單的例子來了解下他的一些是使用方法
首先我們有Hero這個模型
?
@property (nonatomic,copy) NSString * name;@property (nonatomic,copy) NSString * title;@property (nonatomic,assign) NSUInteger age;
在控制其中我們將其初始化并賦值
?
?
?
??? self.hero = [[Hero alloc] init];
??? self.hero.name = @"趙云";
??? self.hero.title = @"將軍";
??? self.hero.age = 87;
現在我們的這個對象基本有值了,那么我們將這個對象的name監聽下他的改變
?
?
?
[self.hero addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
觸發通知并將值改變
?
?
?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
??? self.hero.name = @"張飛";
}
在制定的回調函數中,處理收到的更改通知
?
?
?
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
??? if([keyPath isEqualToString:@"name"])
??? {
??????? NSLog(@"賦值后--%@",self.hero.name);
??????? NSLog(@"新的值--%@",change[@"new"]);
??????? NSLog(@"以前的值--%@",change[@"old"]);
?
??? }
}
回調打印如下:
?
?
?

最后注銷觀察者
?
?
- (void)dealloc{
??? [self.hero removeObserver:self forKeyPath:@"name"];
}
?
?
以上就是iOS應用開發中使用設計模式中的觀察者模式的實例介紹的全部內容,相信大家都了解了,武林技術頻道將繼續為大家研究更多的編程知識,希望對你有幫助!