你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS應用開發中使用設計模式中的觀察者模式的實例

iOS應用開發中使用設計模式中的觀察者模式的實例

編輯:IOS開發綜合

在軟件開發中,無論是那種高級語言中總會伴隨著一些最為常用的設計模式,即便就如iOS開發中與我們打交道最多的無非就是單例模式、觀察者模式和工廠模式了,當然了其他的設置模式也同樣存在在編程的很多地方。下面就就讓我們簡單的了解下觀察者模式吧!
觀察者模式本質上時一種發布-訂閱模型,用以消除具有不同行為的對象之間的耦合,通過這一模式,不同對象可以協同工作,同時它們也可以被復用於其他地方Observer從Subject訂閱通知,ConcreteObserver實現重現ObServer並將其重載其update方法。一旦SubJect的實例需要通知Observer任何新的變更,Subject會發送update消息來通知存儲在其內部類中所注冊的Observer、在ConcreteObserver的update方法的實際實現中,Subject的內部狀態可被取得並進行後續處理。其類圖如下:

201631795044843.jpg (737×317)


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

201631795111827.png (466×255)

通過上面的觀察我們可以發現如果用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"]);

    }
}

回調打印如下:

201631795149534.png (211×54)


最後注銷觀察者

復制代碼 代碼如下:
- (void)dealloc{
    [self.hero removeObserver:self forKeyPath:@"name"];
}


到了這裡觀察者模式中常用的KVO及通知的內容就到這裡,不過要知道這裡談及的只是最基礎的用法,後面我們可能還是有更加深入的探究,或者在後續中可能還會對比iOS中的代理以及Block來探尋下iOS中的消息傳遞機制,再或者像Swift中的didSet、willSet的屬性監聽的方法,這些都是很好玩的內容,不是麼?

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved