RxSwift 系列(二) -- Subject
前言
Subject
是一个代理,它既是Observer
,也是Observable
。因为它是一个Observer
,它可以订阅一个或多个Observable
;因为它是一个Observable
,它又可以被其他的Observer
订阅。它可以传递/转发作为Observer
收到的值,也可以主动发射值。
Subject
在RxSwift
中的实现有四种:
PublishSubject
ReplaySubject
BehaviorSubject
Variable
PublishSubject
代理
我们先以PublishSubject
为例来解释Subject
是一个代理的含义。
let subject = PublishSubject<Int>()
subject.subscribe({ (event) in
print("Event:\(event)")
})
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
Subject
作为一个Observable
提供了subscribe
等方法。在订阅之后,我们调用了onNext()
,向Observer
发射了1
、2
,以及onCompleted()
。打印结果和我们预期的是一样的。
Event:next(1)
Event:next(2)
Event:completed
我们可以调用Subject
的on
系列方法主动给Observer
发送值。
Subject
可以作为代理转发订阅到的结果。例如:
let subject = PublishSubject<Int>()
subject.subscribe({ (event) in
print("Event:\(event)")
})
let reveseSubject = Observable<Int>.create({ (observer) -> Disposable in
observer.onNext(1)
observer.onNext(2)
observer.onCompleted()
return Disposables.create()
})
reveseSubject.subscribe(subject)
subject
订阅了reveseSubject
,并将结果转发给了Observer
。
注意:
Observer
订阅subject
时不会收到订阅之前subject
的值。
let subject = PublishSubject<Int>()
subject.onNext(0)
subject.subscribe({ (event) in
print("Event:\(event)")
})
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
上述代码结果为:
Event:next(1)
Event:next(2)
Event:completed
observer
无法接收到0
这个值。
ReplaySubject
ReplaySubject
和PublishSubject
不同的是,Observer
有可能接收到订阅之前的值。
let subject = ReplaySubject<Int>.create(bufferSize: 1)
subject.onNext(0)
subject.subscribe({ (event) in
print("Event:\(event)")
})
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
上述代码结果为:
Event:next(0)
Event:next(1)
Event:next(2)
Event:completed
ReplaySubject
具有重放(replay)的功能,replay的个数可以通过参数指定。我们可以将其理解为缓存的效果。
一般我们使用ReplaySubject
的时候,都是先发射,后订阅,然后通过指定缓存的大小,可以获取对应的值。(注意:不考虑Error和Completed)。
let subject = ReplaySubject<Int>.create(bufferSize: 1)
subject.onNext(0)
subject.onNext(1)
subject.onNext(2)
subject.onCompleted()
subject.subscribe({ (event) in
print("Event:\(event)")
})
上述代码,我们指定了bufferSize
等于1,所以只缓存了最新的值,打印结果:
Event:next(2)
Event:completed
当我们需要缓存所有值的时候,可以调用createUnbounded()
方法。
ReplaySubject.create(bufferSize: 0) 等同于 PublishSubject()。
BehaviorSubject
BehaviorSubject
类似于ReplaySubject
具有缓存能力,但是略有不同。
- 只缓存一个最新值,类似
ReplaySubject.create(bufferSize: 1)
- 需要提供默认值
let behaviorSubject = BehaviorSubject<Int>(value: 1)
behaviorSubject.subscribe({ (event) in
print("Event:\(event)")
})
打印结果为:
Event:next(1)
使用BehaviorSubject
有一点好处,我们可以确定当Observer
订阅时,至少可以收到最新的一个值。
Variable
Variable
和BehaviorSubject
又很相似,Variable
是BehaviorSubject
的一个封装,同样具备了缓存最新值和提供默认值的能力。但是Variable
没有on
系列方法,只提供了value
属性。
直接对value
进行set
等同于调用了onNext()
方法。
这表明了Variable
不会发射error
也不会发射completed
在Variable
被销毁的时候会调用发射completed
给Observer
在订阅Variable
的时候,我们无法直接调用subscribe
方法,需要先调用asObservable()
方法。
let variable = Variable<Int>(1)
variable.asObservable().subscribe({ (event) in
print("Event:\(event)")
})
variable.value = 2
上述结果为:
Event:next(1)
Event:next(2)
Event:completed
Variable
可以用来储存数据,因为我们可以拥有value
的get
和set
方法。比如:
let variable = Variable(1)
print("Value: \(variable.value)")
variable.value = 2
print("Value: \(variable.value)")
打印结果为:
Value: 1
Value: 2
这是BehaviorSubject
不具备的。
RxSwift 系列(二) -- Subject的更多相关文章
- RxSwift 系列(二)
前言 Subject是一个代理,它既是Observer,也是Observable.因为它是一个Observer,它可以订阅一个或多个Observable;因为它是一个Observable,它又可以被其 ...
- sed修炼系列(二):sed武功心法(info sed翻译+注解)
sed系列文章: sed修炼系列(一):花拳绣腿之入门篇sed修炼系列(二):武功心法(info sed翻译+注解)sed修炼系列(三):sed高级应用之实现窗口滑动技术sed修炼系列(四):sed中 ...
- Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全 Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...
- 前端构建大法 Gulp 系列 (二):为什么选择gulp
系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...
- WPF入门教程系列二十三——DataGrid示例(三)
DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...
- Web 开发人员和设计师必读文章推荐【系列二十九】
<Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发人员和设计师必读文章推荐【系列二十八】
<Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 开发精华文章集锦(jQuery、HTML5、CSS3)【系列二十七】
<Web 前端开发精华文章推荐>2014年第6期(总第27期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发人员和设计师必读精华文章【系列二十六】
<Web 前端开发精华文章推荐>2014年第5期(总第26期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
随机推荐
- mongoDB数据库的简单使用
我的第一篇小文章,以前总是写Evernote. mongodb属于非关系型数据库中的文档型数据库. 1.下载安装mongoDB, 文件自动 存放在这个目录下:C:\Program Files\Mong ...
- angularJS ng-change错误的解决方案
导入文件:<script src="../../js/angular/angular-file-upload/angular-file-upload.js"></ ...
- Android开发的过去、现在和将来
现如今,拥有着 80% 的市场份额的 Android 是最主流的手机操作系统.它运行在无数的智能手机.平板以及其他各种各样的设备上.仅凭这一点,我们是否可以认为 Android 编程是简单而轻松的呢 ...
- CVE-2017-8464远程命令执行漏洞(震网漏洞)复现
前言 2017年6月13日,微软官方发布编号为CVE-2017-8464的漏洞公告,官方介绍Windows系统在解析快捷方式时存在远程执行任意代码的高危漏洞,黑客可以通过U盘.网络共享等途径触发漏洞, ...
- 解决Ubuntu开关机动画不正常方法
联想的笔记本,显卡NVIDIA GT218M,默认使用开源的驱动,但挂起后,再唤醒就黑屏回不到桌面. 1.解决办法:安装NVIDIA专有驱动 $sudo apt-get install nvidia- ...
- java源码学习(四)ArrayList
ArrayList ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单线程环境下, ...
- windows端口占用处理工具
一.描述 笔者在最近使用tomcat时,老是会遇到这种端口占用的问题,便写了这个小的exe,用于解决windows下的端口占用问题. 好吧,其实是我实在记不住CMD下的那几行命令.这玩意的实现比较简单 ...
- 【LeetCode】138. Copy List with Random Pointer
题目: A linked list is given such that each node contains an additional random pointer which could poi ...
- 3.jsp基本语法笔记
1.page标签 <%@ page language="java" import="java.util.*" contentType="text ...
- VMware中Mac OS中显示共享文件夹的方法
在finder 偏好设置里的通用标签下,勾选 “已连接的服务器”