国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

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

2019-10-21 18:55:32
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了iOS應用開發中使用設計模式中的觀察者模式的實例,包括Cocoa框架使用中的KVO機制的相關配合運用,代碼為傳統的Objective-C,需要的朋友可以參考下
 

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

iOS應用開發,設計模式,觀察者模式

 


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

iOS應用開發,設計模式,觀察者模式

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

 

    }
}


回調打印如下:

 

iOS應用開發,設計模式,觀察者模式


最后注銷觀察者

 

復制代碼代碼如下:

- (void)dealloc{
    [self.hero removeObserver:self forKeyPath:@"name"];
}

 

 


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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 三明市| 乌苏市| 米泉市| 新乡市| 马边| 玛多县| 天门市| 吉隆县| 安新县| 仙游县| 北碚区| 梁平县| 兴业县| 西平县| 广汉市| 梁山县| 鸡东县| 敦煌市| 崇仁县| 贺兰县| 景德镇市| 张家港市| 高台县| 孟津县| 元谋县| 灯塔市| 聊城市| 西畴县| 白朗县| 桂平市| 松滋市| 阜城县| 临城县| 曲麻莱县| 安岳县| 辽阳县| 常州市| 仁化县| 西畴县| 崇州市| 清丰县|