RxSwift 系列(九)
前言
看完本系列前面几篇之后,估计大家也还是有点懵逼,本系列前八篇也都是参考RxSwift
官方文档和一些概念做的解读。上几篇文章概念性的东西有点多,一时也是很难全部记住,大家脑子里面知道有这么个概念就行,用的时候,再来查阅一番,慢慢就掌握了。
本篇主要来深入了解一些RxSwift
实战中用到的一些重要知识点,这里面有很多自己的理解,所以不免会有一些错误的地方,还请大家多多交流,如有发现错误的地方,欢迎评论。
概念
Rx
系列的核心就是Observable Sequence
这个相信大家心中已经有所了解了,这里不再啰嗦了,建议大家看看前面几篇文章去了解一下。接下来介绍一些容易混淆和难以理解的概念。
- Observable 和 Observer
- subscribe 和 subscribe(onNext:)
- Dispose 和 DisposeBag
- observeOn() 和 subscribeOn()
- shareReplay
- 自定义operator
- Driver
- map 和 flatMap 何时使用
- UIBindingObserver
Observable 和 Observer
相信大家看前面几篇文章的时候,大量出现这两个东西,为了理解这两个东西,我们先来简单介绍下观察者模式吧。
比如一个宝宝在睡觉,爸爸妈妈不可能时时刻刻待在那看着吧?那样子太累
了。他们该做啥做啥,只要听到宝宝哭声的时候,他们给宝宝喂奶就行了。这就是一个简单的观察者模式。宝宝是被观察者,爸爸妈妈是观察者也称作订阅者,只要被观察者发出了某一个事件,比如宝宝哭声,叫声都是一个事件,订阅者就会做出相应地响应。
理解了观察者模式这两个概念就很好理解了,Observable
就是可被观察的,也就是我们说的宝宝,他也是事件源。而Observer
就是我们的观察者,也就是当收到事件的时候去做某些处理的爸爸妈妈。观察者需要去订阅(subscribe
)被观察者,才能收到Observable
的事件通知消息。
subscribe 和 subscribe(onNext:)
subscribe
是订阅sequence
发出的事件,比如next
事件,error
事件等。而subscribe(onNext:)
是监听sequence
发出的next
事件中的element
进行处理,他会忽略error
和completed
事件。相对应的还有subscribe(onError:)
和 subscribe(onCompleted:)
。
Dispose 和 DisposeBag
当监听一个sequence
的时候,有消息事件来了,我们做某些事情。但是这个sequence
不再发送消息事件了,那么我们的监听也就没有什么存在的价值了,所以我们需要释放我们这些监听资源,其实也就是内存资源释放。
释放某一个监听的时候,我们有两种方式处理:
我们可以手动调用释放方式,但是我们一般不适用这种方式。
// 关于scheduler,我们会在下面讲到
let subscription = Observable<Int>.interval(0.3, scheduler: SerialDispatchQueueScheduler.init(internalSerialQueueName: "scott"))
.observeOn(MainScheduler.instance) //observeOn也会在下面讲到
.subscribe { event in
print(event)
}
Thread.sleep(forTimeInterval: 2.0)
subscription.dispose()
打印结果:
next(0)
next(1)
next(2)
next(3)
next(4)
next(5)
比如上面这个例子,我们创建了一个subscription
监听,在两秒以后我们不需要了,手动调用dispose()
方法,就能释放监听资源,不再打印信息。上面的subscription
不论是在哪个线程中监听,就算在主线程中调用的dispose()
方法一样会销毁资源。
除了上述手动释放资源外,还有一种自动方式,推荐大家使用这种方式,这种方式就像iOS
中的ARC
,会在适当的时候销毁观察者,自动释放资源。
let disposeBag = DisposeBag()
Observable<Int>.empty()
.subscribe { event in
print(event)
}
.addDisposableTo(disposeBag)
如上个例子,我们创建一个disposeBag
来盛放我们需要管理的资源,然后把新建的监听都放进去,会在适当的时候销毁这些资源。如果你需要立即释放资源只需要新建一个DisposeBag()
,那么上一个DisposeBag
就会被销毁。
observeOn() 和 subscribeOn()
这两个东西刚开始看的时候也是一脸懵逼,就知道最好多用observeOn()
,但是不知道为什么,下面我们就来揭开它们的面纱看下它们的真面目吧。
区别其实我感觉就一句话,subscribeOn()
设置起点在哪个线程,observeOn()
设置了后续工作在哪个线程。例如:
someObservable
.doOneThing() // 1
.observeOn(MainRouteScheduler.instance) // 2
.subscribeOn(OtherScheduler.instance) // 3
.subscribeNext { // 4
......
}
.addDisposableTo(disposeBag)
- 所有动作都发生在当前的默认线程
observeOn()
转换线程到主线程,下面所有的操作都在主线程subscribeOn()
规定动作一开始不是发生在默认线程,而是在OtherScheduler
了。- 如果我们之前没有调用
observeOn()
,那么这边会在OtherScheduler
发生,但是我们前面调用了observeOn()
,所以这个动作会在主线程中调用。
总结一下:
subscribeOn()
只是影响事件链开始默认的线程,而observeOn()
规定了下一步动作发生在哪个线程中。
shareReplay
看官方项目里面的Demo
时,我也很疑惑,为什么很多的sequence
后面都有shareReplay(1)
呢?想的昏头涨脑。
这里我就给大家讲解一下我的理解吧。先看一个例子:
let disposeBag = DisposeBag()
let observable = Observable.just("
RxSwift 系列(九)的更多相关文章
- RxSwift 系列(九) -- 那些难以理解的概念
前言 看完本系列前面几篇之后,估计大家也还是有点懵逼,本系列前八篇也都是参考RxSwift官方文档和一些概念做的解读.上几篇文章概念性的东西有点多,一时也是很难全部记住,大家脑子里面知道有这么个概念就 ...
- RxSwift 系列(三) -- Combination Operators
RxSwift 系列(三) -- Combination Operators 前言 本篇文章将要学习如何将多个Observables组合成一个Observable. Combination Opera ...
- java基础解析系列(九)---String不可变性分析
java基础解析系列(九)---String不可变性分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---In ...
- java多线程系列(九)---ArrayBlockingQueue源码分析
java多线程系列(九)---ArrayBlockingQueue源码分析 目录 认识cpu.核心与线程 java多线程系列(一)之java多线程技能 java多线程系列(二)之对象变量的并发访问 j ...
- 分布式系列九: kafka
分布式系列九: kafka概念 官网上的介绍是kafka是apache的一种分布式流处理平台. 最初由Linkedin开发, 使用Scala编写. 具有高性能,高吞吐量的特定. 包含三个关键能力: 发 ...
- information_schema系列九
information_schema系列九 1:INNODB_SYS_FOREIGN 这个表存储的是INNODB关于外键的元数据信息 Column name Description ID 外键的名 ...
- RxSwift 系列(三)
RxSwift 系列(三) -- Combination Operators 前言 本篇文章将要学习如何将多个Observables组合成一个Observable.Combination Operat ...
- struts2官方 中文教程 系列九:Debugging Struts
介绍 在Struts 2 web应用程序的开发过程中,您可能希望查看由Struts 2框架管理的信息.本教程将介绍两种工具,您可以使用它们来查看.一个工具是Struts 2的配置插件,另一个是调试拦截 ...
- Bing Maps进阶系列九:使用MapCruncher进行地图切片并集成进Bing Maps
Bing Maps进阶系列九:使用MapCruncher进行地图切片并集成进Bing Maps 在Bing Maps开发中,由于各种应用功能的不同,更多的时候用户可能需要将自己的一部分图片数据作为地图 ...
随机推荐
- 如何发布一个自定义Node.js模块到NPM(详细步骤,附Git使用方法)
咱们闲话不多说,直接开始! 由于我从没有使用过MAC,所以我不保证本文中介绍的操作与MAC一致. 文章开始我先假定各位已经在window全局安装了Node.js,下面开始进行详细步骤介绍: 本文本着, ...
- css3图片响应式布局
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Web攻防系列教程之 Cookie注入攻防实战
摘要:随着网络安全技术的发展,SQL注入作为一种很流行的攻击方式被越来越多的人所知晓.很多网站也都对SQL注入做了防护,许多网站管理员的做法就是添加一个防注入程序.这时我们用常规的手段去探测网站的SQ ...
- hdu 2119 Matrix(二分匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2119 Matrix Time Limit: 5000/1000 MS (Java/Others) ...
- sublime 直接运行php代码
只需要简单的配置就可以进行 操作. 首先配置php环境变量 配置完成后打开sublime 点击新编译系统 { "cmd": ["php", "$fil ...
- 首次成功的web渗透
web渗透 今天给大家讲一个最近做的一件令我振奋的一件事情 渗透培训刚刚结束的第二天 我在公网上挖到了我人生中的第一个站 总体来说个人真的很振奋人心 这个网站还没有进行更改但我已经通知了他们 ...
- nginx与PHP的关系和交互方式【转】
nginx与PHP的关系. 对比, apache和PHP的关系, 将PHP安装成apache的一个功能模块, 导致的结果, 对外只有一个apache程序, PHP并不独立出现, 仅仅是apache的模 ...
- WebService初识
Web service 是一种跨编程语言和跨操作系统平台的远程调用技术,即跨平台远程调用技术.也就是说,不管是J2EE架构,还是.net架构 只要按照规范就可以进行通信,实现数据交互等. 这里说的&q ...
- 51Nod 1352 集合计数(扩展欧几里德)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1352 题目大意: 给出N个固定集合{1,N},{2,N-1} ...
- 使用 PHP 构建的 Web 应用如何避免 XSS 攻击
本文首先简单介绍开发测试人员如何对 Web 应用进行 XSS 漏洞测试,如何借助工具绕过客户端 JavaScript 校验输入恶意数据:然后针对使用 PHP 语言构建的 Web 站点,从在输出端对动态 ...