在软件开发中,无论是那种高级语言中总会伴随着一些最为常用的设计模式,即便就如iOS开发中与我们打交道最多的无非就是单例模式、观察者模式和工厂模式了,当然了其他的设置模式也同样存在在编程的很多地方。下面就就让我们简单的了解下观察者模式吧!

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

观察者模式.png

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

观察者模式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"]);}
}

回调打印如下:

dayin.png

最后注销观察者

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

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

文/不听故事的王同学(简书作者)
原文链接:http://www.jianshu.com/p/56d9417c3a04
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

iOS开发之观察者模式相关推荐

  1. iOS开发之观察者模式初探

    2019独角兽企业重金招聘Python工程师标准>>> 观察者模式本质上时一种发布-订阅模型,用以消除具有不同行为的对象之间的耦合,通过这一模式,不同对象可以协同工作,同时它们也可以 ...

  2. iOS开发-观察者模式

    观察者模式也被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己.观察者模式中 ...

  3. iOS开发系列--通知与消息机制

    http://www.cocoachina.com/ios/20150318/11364.html 概述 在多数移动应用中任何时候都只能有一个应用程序处于活跃状态,如果其他应用此刻发生了一些用户感兴趣 ...

  4. iOS开发-简单工厂模式

    设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性.概念很长,iOS开发中最常 ...

  5. 开发必看 | iOS开发常用设计模式!

    ios开发学习中,经常弄不清楚ios的开发模式,今天我们就来进行简单的总结和探讨~ (一)代理模式 应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现. 优势:解耦合 敏捷 ...

  6. IOS开发基础之使用AFNetworking框架下载服务器资源图片

    IOS开发基础之使用AFNetworking框架下载服务器资源图片 info.plist加入这句 <key>NSAppTransportSecurity</key> <d ...

  7. IOS开发中的几种设计模式

    ios开发学习中,经常弄不清楚ios的开发模式,今天我们就来进行简单的总结和探讨~ (一)代理模式 应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现. 优势:解耦合 敏捷 ...

  8. iOS开发设计模式详解

    在软件开发中一般认为有23种设计模式(design pattern),这是软件开发中的较高的境界了.在iOS开发中最常用的有哪些设计模式呢?我们今天来分析一下: 一.[代理模式] 使用场景:当一个类的 ...

  9. iOS开发——BAT网易笔试面试题参考答案

    阿里B2B - 一面 1,load方法执行顺序,分类和主类的load方法顺序,两个分类的load方法顺序,跟main函数的顺序 2,sqllite的跟orcale这些大型的数据库的机制有什么不同的? ...

  10. 浅谈设计模式在iOS开发实战项目中的应用

    在我们日常的开发中设计模式伴随着项目的各个模块,巧妙地使用设计模式可以让我们写出更高效,简洁,优美的代码.可是因为对于设计模式的不熟悉,很多高效的设计模式并没有被很好地使用起来,而最近也正好在revi ...

最新文章

  1. 售价910元!周志华等人英文新书《演化学习》出炉!
  2. leetcode算法题--不同的二叉搜索树
  3. djngo快速实现--使用Bootstrap
  4. mysql 四 表操作
  5. android 电容屏(二):驱动调试之基本概念篇
  6. java集合的批量新建_java使用Arrays.asList快速创建List集合
  7. C++matrix chain multiplication矩阵链乘法算法的实现(附完整源码)
  8. 面向对象进阶-反射(二)重要知识点
  9. java 上传远程图片,java上传图片到另一台服务器上,怎么解决
  10. php中socket的使用
  11. 《PHP和MySQL Web开发从新手到高手(第5版)》一2章 MySQL简介2.1 数据库简介
  12. A*算法一个简单的记录
  13. SharedMaterial的一些问题
  14. 软件测试和初级会计哪个简单,2018年初级会计app刷题哪个好?
  15. KTV用什么收银管理系统管店?
  16. code 128 字体扫描不可识别
  17. AfxBeginThread第二个参数LPVOID pParam的使用
  18. TPU是什么材料,tpu材料属于塑料吗?
  19. android用bmob实现评论,Bmob在Android上的应用
  20. 位运算符最详细的解释(java)

热门文章

  1. excel的最大行数和列数
  2. php 读取图片bgr,快速解决cv2.imread()读取图像为BGR的问题
  3. 花式感染 Windows PE 病毒的一百种方法,你中过招吗?
  4. Seraph‘s Last Stand(塞拉弗的最后一站)技能翻译
  5. 网吧用服务器做虚拟化,网吧内共享服务器搭建
  6. 编程十年 (13):毁人不倦1
  7. 有一种焦虑叫三十不立
  8. 变频器在电机驱动中的作用
  9. 苹果官方付费升级内存_vivo推出内存扩容服务:良心还是坑钱?
  10. 今日接手一个项目,服务器重启后,mysql启动失败