博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发之观察者模式初探
阅读量:5969 次
发布时间:2019-06-19

本文共 3522 字,大约阅读时间需要 11 分钟。

hot3.png

观察者模式本质上时一种发布-订阅模型,用以消除具有不同行为的对象之间的耦合,通过这一模式,不同对象可以协同工作,同时它们也可以被复用于其他地方Observer从Subject订阅通知,ConcreteObserver实现重现ObServer并将其重载其update方法。一旦SubJect的实例需要通知Observer任何新的变更,Subject会发送update消息来通知存储在其内部类中所注册的Observer、在ConcreteObserverupdate方法的实际实现中,Subject的内部状态可被取得并进行后续处理。其类图如下:

 

1240

观察者模式.png

由上面我们可以发现观察者模式无非在是定义对象间的一种一对多的依赖关系,并且当一个对象的状态发生改变的时候,所有依赖于它的对象都会得到通知且自动更新。即如果Subject允许其他观察者(实现了观察者接口的对象)对这个Subject的改变进行请阅,当Subject发送了变化,那么Subject会将这个变化发送给所有的观察者,观察者就能对Subject的变化做出更新。其时序图如下

 

1240

观察者模式2.png

通过上面的观察我们可以发现如果用N个Observer来拓展Subject的行为,这些Observer具有处理存储在Subject中的信息的特定实现,这样也就实现了前面所说的消除不同对象间的耦合的功能了。

那么了解了这些我们可能就会更像了解下我们在什么时候才会去使用观察者模式呢?

  • 当需要将改变通知所有的对象时,而你又不知道这些对象的具体类型
  • 改变发生在同一个对象中,并需要改变其他对象将相关的状态进行更新且不知道有多少个对象。

而同样的在我们日常的开发中在Cocoa Touch框架中的的两种经常打交道的技术KVO与通知都实现了观察者模式,所以下面我们讨论的重点也就是基于这两个方面的。

通知

在之前的博文中曾经简单的提到过一些通知的基础使用方法,所以一些基本的使用方法再次就不赘述。言归正传,在Cocoa Touch框架中NSNotificationCenterNSNotification对象实现了一对多的模型。通过NSNotificationCenter可以让对象之间进行通讯,即便这些对象之间并不认识。下面我们来看下NSNotificationCenter发布消息的方法:
NSNotification  * subjectMessage = [ NSNotification  notificationWithName:@"subjectMessage"  object: self];    NSNotificationCenter  * notificationCenter = [ NSNotificationCenter  defaultCenter];    [notificationCenter postNotification:subjectMessage];

通过上面的代码我们创建了一个名为subjectMessageNSNotification对象,然后通过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];}

了解过通知之后我们来看一下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"]);    }}

回调打印如下:

 

1240

dayin.png

最后注销观察者

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

到了这里观察者模式中常用的KVO通知的内容就到这里,不过要知道这里谈及的只是最基础的用法,后面我们可能还是有更加深入的探究,或者在后续中可能还会对比iOS中的代理以及Block来探寻下iOS中的消息传递机制,再或者像Swift中的didSetwillSet的属性监听的方法,这些都是很好玩的内容,不是么?

 

文/晓风沐晨(简书作者)

原文链接:http://www.jianshu.com/p/56d9417c3a04
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

转载于:https://my.oschina.net/yangtaoaaa/blog/685980

你可能感兴趣的文章
电信网络拓扑图自动布局
查看>>
C#中List〈string〉和string[]数组之间的相互转换
查看>>
洛谷P1108 低价购买[DP | LIS方案数]
查看>>
通达信里的统计函数及区块背景函数
查看>>
redis主从配置<转>
查看>>
8 行 Node.js 代码实现代理服务器
查看>>
水印,图片验证码
查看>>
C#编程(七十六)----------使用指针实现基于栈的高性能数组
查看>>
PostgreSql 分页limit
查看>>
在MySQL中创建cm-hive使用的数据库及账号
查看>>
linux下限制ip访问
查看>>
linux添加环境变量
查看>>
ASP.NET MVC 入门8、ModelState与数据验证
查看>>
组件居中显示 安卓
查看>>
delete
查看>>
sql server生成不重复的时间字符串
查看>>
DataBase 之 数据库设计六大范式
查看>>
比特币钱包安全
查看>>
Lucene就是这么简单
查看>>
2015年第6届蓝桥杯Java B组省赛试题解析
查看>>