一,概念

  观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

二,类图

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

notification

广播,感兴趣可以了解下java中的观察者实现原理,如出一辙。java可以看的源码。

1注册与注销广播

deinit {
NotificationCenter.default.removeObserver(self)
} required init(coder aCoder: NSCoder) {
super.init(coder: aCoder)!
} override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(changeColor(notf:)), name: NSNotification.Name(rawValue: kChangeBackgroundColour), object: nil) } @objc func changeColor(notf: Notification) {
self.view.backgroundColor = notf.userInfo?["bg_color"] as? UIColor;
}

2发送广播

@IBAction func changeToRed(_ sender: Any) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kChangeBackgroundColour), object: nil, userInfo: ["bg_color": UIColor.red])
}

KVO:

只有 NSObject 才能支持 KVO。

Swift 4中的一个对此有影响的改变是继承 NSObject 的 swift class 不再默认全部 bridge 到 OC。然而 KVO 又是一个纯 OC 的特性,所以如果是 swift class 需要在声明的时候增加 @objcMembers 关键字。否则在运行的时候你会得到一个 error:

fatal error: Could not extract a String from KeyPath
Swift.ReferenceWritableKeyPath

另外一件事就是被观察的属性需要用dynamic修饰,否则也无法观察到。

一个好消息是不需要在对象被回收时手动 remove observer。但是这也带来了另外一个容易被忽略的事情:观察的闭包没有被强引用,需要我们自己添加引用,否则当前函数离开后这个观察闭包就会被回收了。

@objcMembers class OCClass: NSObject {
dynamic var name: String init(name: String) {
self.name = name
}
} class ViewController: UIViewController { var swiftClass: OCClass!
var ob: NSKeyValueObservation! override func viewDidLoad() {
super.viewDidLoad() swiftClass = OCClass(name: "oc")
ob = swiftClass.observe(\.name) { (ob, changed) in
let new = ob.name
print(new)
}
swiftClass.name = "swift4"
}
}

KVO 之后返回的是一个 NSKeyValueObservation 实例,需要自己控制这个实例的生命周期。

设计模式-(10)观察者模式 (swift版)的更多相关文章

  1. JavaScript设计模式(10)-观察者模式

    观察者模式 1. 介绍 发布者与订阅者是多对多的方式 通过推与拉获取数据:发布者推送到订阅者或订阅者到发布者那边拉 使并行开发的多个实现能彼此独立地进行修改 其实我们在前端开发中使用到的时间监听就是浏 ...

  2. 设计模式之 观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...

  3. Swift版iOS游戏框架Sprite Kit基础教程下册

    Swift版iOS游戏框架Sprite Kit基础教程下册 试读下载地址:http://pan.baidu.com/s/1qWBdV0C 介绍:本教程是国内唯一的Swift版的Spritekit教程. ...

  4. Swift版音乐播放器(简化版),swift音乐播放器

    这几天闲着也是闲着,学习一下Swift的,于是到开源社区Download了个OC版的音乐播放器,练练手,在这里发扬开源精神, 希望对大家有帮助! 这个DEMO里,使用到了 AudioPlayer(对音 ...

  5. iOS可视化动态绘制八种排序过程(Swift版)

    前面几篇博客都是关于排序的,在之前陆陆续续发布的博客中,我们先后介绍了冒泡排序.选择排序.插入排序.希尔排序.堆排序.归并排序以及快速排序.俗话说的好,做事儿要善始善终,本篇博客就算是对之前那几篇博客 ...

  6. swift版的CircleView

    swift版的CircleView 效果图 源码 // // CircleView.swift // CircleView // // Created by YouXianMing on 15/10/ ...

  7. swift版的GCD封装

    swift版的GCD封装 说明 本人针对swift封装了GCD,包括GCDQueue,GCDGroup,GCDTimer以及GCDSemaphore,使用较为便利. 源码 https://github ...

  8. swift版的StringAttribute

    swift版的StringAttribute 效果 源码 https://github.com/YouXianMing/Swift-StringAttribute // // StringAttrib ...

  9. swift版的元组

    swift版的元组 说明 元组的内容并不多,使用的话跟普通变量类似,以下是测试源码: // // ViewController.swift // Tuples // // Created by You ...

  10. swift版的枚举变量

    swift版的枚举变量 swift的枚举类型跟普通的类是极为类似的,使用的时候,请不要以为他是一个常量,以下是测试用源码 // // ViewController.swift // SwiftEnum ...

随机推荐

  1. luogu1447 [NOI2010]能量采集

    考虑暴力,答案显然是 \(\sum_{i=1}^n\sum_{j=1}^m(2(\gcd(i,j)-1)+1)=\sum_{i=1}^n\sum_{j=1}^m(2\gcd(i,j)-1)\). 考虑 ...

  2. STM32F407 串口通信实验 视频第27节 个人笔记

    前言 第26节也是串口,笔记链接在此:https://www.cnblogs.com/YuQiao0303/p/10019362.html github地址:https://github.com/Yu ...

  3. springmvc ajax传值详解

  4. php对象(继承,多态)

    /2.继承//function abc(){// $arr = func_get_args();//}//子类只能有一个父类 一个父类 可以有多个子类//override 重写//overlood 重 ...

  5. Java 学习(4):基本数据类型,变量类型

    目录 --- 基本数据类型 --- 变量类型 基本数据类型 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用 ...

  6. Java设计模式之(工厂模式)

    工厂模式: 工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 简单工厂模 ...

  7. 用DW制作简单的浮动广告

    原文发布时间为:2008-11-08 -- 来源于本人的百度文章 [由搬家工具导入] 浮动广告可以用层和时间轴结合做出,先选择你的dreamweaver“窗口”,然后从“窗口”菜单中选择“时间轴”,时 ...

  8. 积累js中的一些问题及解决方案

    一.取字符串的第i位不兼容的问题 1.问题:对于字符串str来说,要获取第i位,常见的是str[i],但是在低版本的浏览器中不兼容,例如ie7. 2.解决:使用str.charAt(i); 二.使用定 ...

  9. msp430项目编程06

    msp430中项目---设计扫描键盘 1.扫描键盘工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(键盘驱动) 5.项目总结 msp430项目编程 msp430入门学习

  10. Git学习之常见错误 git push 失败

    Git学习之常见错误 git push 失败 问题描述: git push Counting objects: , done. Delta compression using up to thread ...