IOS模式之三:观察者模式

作者: GitHubPorter | 来源:发表于2016-06-15 14:17 被阅读336次

什么是观察者模式

观察者模式

什么是观察者模式?你曾经订阅过报纸吗?在订阅报纸的时候,你不用去任何地方,只需要将你的个人地址信息以及订阅信息告诉出版社,出版社就知道如何将相关报纸传递给你。这种模式的第二个名称叫做发布/订阅模式。

在GoF中是这样描述观察者模式的——观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式的的思想非常简单,Subject(主题)允许别的对象——观察者(这些对象实现了观察者接口)对这个Subject的改变进行订阅和取消订阅。当Subject发生了变化——那么Subject会将这个变化发送给所有的观察者,观察者就能对Subject的变化做出更新。在这里,Subject是报纸的出版社,而观察者则是订阅报纸的我和你,当Subject发生变化——有新的报纸,会做出通知——将报纸发送给所有的订阅者。

什么时候使用观察者模式?

当你需要将改变通知所有的对象时,而你又不知道这些对象的具体类型,此时就可以使用观察者模式。 改变发生在同一个对象中,并在别的地方需要将相关的状态进行更新。

iOS中观察者模式的实现方法

在iOS中观察者模式的实现有三种方法:Notification、KVO以及标准方法。

1.Notification

Notification - NotificationCenter机制使用了操作系统的功能。通过NSNotificationCenter可以让对象之间进行进行通讯,这些对象相互间可以不认识。当你用一个并行的流来推送通知,或者刷新数据库,并希望在界面中能够看到时,这非常有用。

NotificationCenter发布消息的方法如下所示:

NSNotification  * broadcastMessage = [ NSNotification  notificationWithName: AnyNotification  object: Self ];

NSNotificationCenter  * notificationCenter = [ NSNotificationCenter  defaultCenter];

[NotificationCenter postNotification: broadCastMessage];

上面的代码中,创建了一个NSNotification类型的对象,并指定名称为”broadcastMessage”,然后通过notificationCenter来发布这个消息。

要订阅感兴趣的对象中的相关事件,可以按照如下方法进行:

NSNotificationCenter  * notificationCenter = [ NSNotificationCenter  defaultCenter];

[NotificationCenter addObserver: Self  selector: @ selector (update:) name: AnyNotification  object: nil ];

如上代码所示:订阅了一个事件,并通过@selector指定了一个方法。

// 收到通知中心发来的通知

-(void)update:(NSNotification *) notification

{

   if ([[notification name] isEqualToString:AnyNotification])

        NSLog (@"成功收到通知中心发来的名为%@的通知", AnyNotification);

}

下面是运行上面代码,在控制台输出的内容:

2013-05-05 23:43:15.570 ObserverPattern[1738:c07] 成功收到通知中心发来的名为broadcastMessage的通知

2.KVO

一般情况下对于使用Property的属性,objc会为其自动添加键值观察功能,你只需要写一句@property (noatomic, assign) float age就能够获得age的键值观察功能。

通过KVO,某个对象中的特定属性发生了改变,别的对象可以获得通知。苹果官方文档对KVO有了很好的解释:Key-Value Observing Programming Guide。下面两种方法都可以改变对象中属性的值:

kvoSubj.changeableProperty = @"新的一个值";

[kvoSubj setValue:@"新的一个值" forKey:@"changeableProperty"];

上面这种值改变的灵活性可以让我们对键值进行观察。

下面是新建的一个类KVOSubject,这个类中有一个属性changeableProperty:

@interface KVOSubject : NSObject

@property (nonatomic, strong) NSString *changeableProperty;

@end

@implementation KVOSubject

@end

接着新建了另外一个类KVOObserver,通过该类可以监听changeableProperty属性值的改变。

@interface KVOObserver : NSObject

@end

3.

@implementation KVOObserver

-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

NSLog(@"KVO:值发生了改变");

}

@end

如上代码所示,KVOObserver类只有一个方法observeValueForKeyPath。当changeableProperty属性值的改变时,这个方法会被调用。下面是测试的代码:

- (IBAction)btnKVOObservationTest:(id)sender {

KVOSubject *kvoSubj = [[KVOSubject alloc] init];

KVOObserver *kvoObserver = [[KVOObserver alloc] init];

[kvoSubj addObserver:kvoObserver forKeyPath:@"changeableProperty"                 options:NSKeyValueObservingOptionNew context:nil];

kvoSubj.changeableProperty = @"新的一个值";

[kvoSubj setValue:@"新的一个值" forKey:@"changeableProperty"];

[kvoSubj removeObserver:kvoObserver forKeyPath:@"changeableProperty"];

}

执行上面的代码,可以看到控制台输出如下结果:

2013-05-05 23:10:20.789 ObserverPattern[1358:c07] KVO:值发生了改变

2013-05-05 23:10:20.790 ObserverPattern[1358:c07] KVO:值发生了改变标准方法

3.标准方法

先来看看Gof中对观察者模式定义的结构图:

标准方法的实现是这样的:Subject(主题)知道所有的观察者,但是不知道它们的类型。下面我们就从创建Subject和Observer(观察者)的协议(protocol)开始。

@protocol StandardObserver

-(void) valueChanged:(NSString *)valueName newValue:(NSString *) newValue;

@end

@protocol StandardSubject

-(void) addObserver:(id) observer;

-(void) removeObserver:(id) observer;

-(void) notifyObjects;

@end

下面,我们来创建一个Subject的implementation (实现)

@interface StandardSubjectImplementation : NSObject

{

    @private NSString *_valueName;

    @private NSString *_newValue;

}

@property (nonatomic, strong) NSMutableSet *observerCollection;

-(void)changeValue:(NSString *)valueName andValue:(NSString *) newValue;

@end

@implementation StandardSubjectImplementation

-(NSMutableSet *) observerCollection

{

  if (_observerCollection == nil)

        _observerCollection = [[NSMutableSet alloc] init];

   return _observerCollection;

}

-(void) addObserver:(id)observer

{

    [self.observerCollection addObject:observer];

}

-(void) removeObserver:(id)observer

{

    [self.observerCollection removeObject:observer];

}

-(void) notifyObjects

{

   for (id observer in self.observerCollection) {

        [observer valueChanged: _valueName newValue:_newValue];

    }

}

-(void)changeValue:(NSString *)valueName andValue:(NSString *) newValue

{

   _newValue = newValue;

    _valueName = valueName;

    [self notifyObjects];

}

@end

接下来是Observer的implementation (实现):

@interface SomeSubscriber : NSObject

@end

@implementation SomeSubscriber

-(void) valueChanged:(NSString *)valueName newValue:(NSString *)newValue

{

   NSLog(@"SomeSubscriber输出: 值 %@ 已变为 %@", valueName, newValue);

}

@end

@interface OtherSubscriber : NSObject

@end

@implementation OtherSubscriber

-(void) valueChanged:(NSString *)valueName newValue:(NSString *)newValue

{

   NSLog(@"OtherSubscriber输出: 值 %@ 已变为 %@", valueName, newValue);

}

@end

下面是演示的代码:

StandardSubjectImplementation * subj = [[StandardSubjectImplementation alloc] init];

SomeSubscriber * someSubscriber = [[SomeSubscriber alloc] init];

OtherSubscriber * otherSubscriber = [[OtherSubscriber alloc] init];

[Subj addObserver: someSubscriber];

[Subj addObserver: otherSubscriber];

[subj changeValue:@"version" andValue:@"1.0.0"];

参考博客:

http://www.cocoachina.com/industry/20130506/6132.html

相关文章

  • iOS模式设计之--行为型:7、观察者模式(Observer)

    iOS模式设计之--行为型:7、观察者模式(Observer)

  • 常用设计模式整理

    ios面试题(整理) ios常用的设计模式有哪些? MVC模式、委托模式、观察者模式(kvo、kvc、通知机制)、...

  • IOS模式之三:观察者模式

    什么是观察者模式 什么是观察者模式?你曾经订阅过报纸吗?在订阅报纸的时候,你不用去任何地方,只需要将你的个人地址信...

  • 面向对象设计模式-6大原则

    什么是设计模式? iOS内平时有很多设计模式,如:delegate,单例模式,观察者模式,工厂模式…… 设计模式是...

  • 浅论iOS设计模式

    一 iOS中都有什么设计模式? iOS中分别有以下设计模式: 1.代理模式 2.观察者模式 3.MVC模式 4....

  • 浅谈iOS设计模式

    序言:设计模式是一种编码经验,设计模式有MVC模式,工厂模式,单例模式,委托模式,MVVM模式,观察者模式。iOS...

  • iOS设计模式总结

    iOS常用的设计模式: KVO/通知 -------> 观察者模式 观察者模式定义了一种一对多的依赖关系,让多个观...

  • 《iOS开发》--------常用的设计模式

    关于iOS开发中的设计模式,当下有集中最常用的设计模式:代理模式、观察者模式、MVC模式、单例模式、策略模式、工厂...

  • IOS 设计模式

    IOS开发中几种设计模式:单例模式、观察者模式、MVC模式、代理模式 一、单例模式 场景:确保程序运行期某个类,只...

  • iOS面试题13-其他

    《2018 iOS面试题系列》 1.常用的设计模式 单例模式组合模式观察者模式代理模式享元模式工厂方法模式抽象工厂...

网友评论

    本文标题:IOS模式之三:观察者模式

    本文链接:https://www.haomeiwen.com/subject/hfxpdttx.html