全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

RxSwift学习之Observable的新建、订阅及取消订阅

前言

我们在前一篇基础之上,本文将会介绍 RxSwift 中的 Observables 部分。

在 RxSwift 中 Observable 也被称为 Observable Sequence、Sequence、Stream。Observable 会以异步的方式不断的发射事件形成事件流,并且数据也会沿着事件流进行传播。下图是事件流的图像化表示:

其中从左到右的箭头代表时间轴,而三个圆圈则构成了可观察序列。而整个过程会按照从左到右的顺序。另外,事件可能在可观察序列生命周期内的任意时刻被触发。

Observable 生命周期

上图中的三个圆圈其实就是 RxSwift 中的 next 事件。除了 next 之外,RxSwift 中还有 completed 和 error 事件,而这两者都意味事件流生命周期的总结。

completed 所表示的正常终结:

error 所表示的异常终结:

在源码中这三类事件的定义如下:

/// Represents a sequence event.
///
/// Sequence grammar: 
/// **next\* (error | completed)**
public enum Event<Element> {
 /// Next element is produced.
 case next(Element)

 /// Sequence terminated with an error.
 case error(Swift.Error)

 /// Sequence completed successfully.
 case completed
}

在代码中,我们可以清晰的看到 next 事件会携带一个实例进行传播,error 事件会携带一个 Error 实例,completed 则什么都不会携带。

新建 Observable

在所有 Observable 对象的创建方法中,最简单的就是 just :

// 1
let one = 1 
let two = 2 
let three = 3

// 2 
let observable: Observable<Int> = Observable<Int>.just(one)

作为类方法 just 所创建的 Observable 对象只会包含一个元素。但是大多数时候,Observable 对象在其生命周期内会包含多个元素,而创建方法也很简单:

let observable2 = Observable.of(one, two, three)

可能上面的代码会给人一种误导,让人觉得 observable2 中的数据可能是一个数组类型。不过好在我们可以通过下面的代码进行检验:

observable2.subscribe(onNext: { element in
  print(element) 
 })
 
/* 打印结果:
1
2
3
*/

而真正创建数组类型变量的方法是:

let observable3 = Observable.of([one, two, three])
observable3.subscribe(onNext: { element in
  print(element) 
 })
 
/* 打印结果:
[1, 2, 3]
*/

上面只是几个常用的 Observable 创建方法,更多的内容可以去查文档和代码。

订阅 Observable

在日常 iOS 编程中,通知模式可以说是使用频率相当高的一个设计模式。我们通过 NotificationCenter 实现消息的广播和订阅。下面是一个典型的通知模式代码用于处理 UIKeyboardDidChangeFrame 消息:

let observer = NotificationCenter.default.addObserver( 
forName: .UIKeyboardDidChangeFrame, 
object: nil, 
queue: nil ) { notification in 
 // 闭包
}

RxSwift 中的订阅操作也非常简单,只需要调用 subscribe 方法就行了。不过与 NotificationCenter 机制不同的是,RxSwift 中每一个订阅都是唯一的并没有一个类似 default 这样的全局单例对象。

更为重要的是,在没有订阅者的时候 Observable 对象不会发送通知。另外, Observable 对象实际上是一个序列,所以订阅操作有点类似于反复调用 Swift 标准库里中迭代器 Iterator 对象 next 函数:

let sequence = 0..<3

var iterator = sequence.makeIterator()

while let n = iterator.next() { 
 print(n)
}

/* 打印结果: 
0 1 2 
*/

不过 RxSwift 订阅操作明显比这个来的更直接,并且可以一次实现对 next、error、completed 事件的的处理。一个简单的订阅操作示例:

let one = 1 
let two = 2 
let three = 3

let observable = Observable.of(one, two, three)

observable.subscribe { event in 
 print(event) 
}

上面代码的订阅操作非常简单:打印出 observable 声明周期内的所有事件。正常情形下,它的结果如下:

next(1) 
next(2) 
next(3) 
completed

当然,有时候我们可能只是需要 observable 所发射的数据:

observable.subscribe { event in
 if let element = event.element { 
  print(element)
 }
}

/* 打印结果:
1 
2 
3
*/

又或者,我们需要对不同事件区别处理:

observable .subscribe(
 onNext: { element in 
  print(element) 
 },
 onCompleted: { 
  print("Completed")

 }
)

取消订阅并消除内存泄漏

Observable 对象只有在存在订阅的情形下才会进行数据发送操作,而且会在 error 或 completed 事件触发时结束其生命周期。但是,有时候我们可能需要手动取消订阅并提前终结 Observable 对象的生命。

let observable = Observable.of("A", "B", "C")

let subscription = observable.subscribe { event in
 print(event)
}

上面代码非常简单这里就不再细诉了,这里我们直接来看取消订阅的操作。其实,取消订阅的操作非常之简单只需一行代码:

subscription.dispose()

当然,手动对每一个订阅对象进行取消操作显然是一件枯燥的工作。所以 RxSwift 为大家提供了一个更为简单的方案。只需在订阅时调用 .addDisposableTo() 添加一个 DisposeBag 类型对象,我们就能在 DisposeBag 对象销毁时取消所有绑定订阅对象的取消动作。

let disposeBag = DisposeBag()

Observable.of("A", "B", "C")
 .subscribe { 
  3 print($0)
 } 
 .addDisposableTo(disposeBag)

这里我们之所以需要进行 DisposeBag 对象绑定或者手动调用 dispose() 进行取消订阅操作,是因为如果不这么做的话 Observable 对象在生命周期完结时会存在内存泄漏的问题。

总结

本文只是简单的介绍了 Observables 一些常见基础内容。这里还有很多更深入的内容没有介绍,例如:empty 和 never 类型的订阅、使用 Create 实现自定义 Observable 以及 Error 类型的自定义实现。如果你有兴趣的话,我强烈建议你查阅官方文档和代码。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# rxswift  # observable  # 教程  # swift  # RxSwift实现替换delegate的方法示例  # 浅谈RxSwift 网络请求  # RxSwift使用技巧之过滤操作详解  # RxSwift学习教程之类型对象Subject详解  # RxSwift学习教程之基础篇  # RxSwift发送及订阅 Subjects、Variables代码示例  # 是一个  # 的是  # 只需  # 能在  # 我们可以  # 自定义  # 绑定  # 流进  # 几个  # 如果你  # 文档  # 让人  # 是因为  # 也会  # 多个  # 将会  # 才会  # 会在  # 也很  # 只会 


相关文章: 如何用免费手机建站系统零基础打造专业网站?  广州顶尖建站服务:企业官网建设与SEO优化一体化方案  整蛊网站制作软件,手机不停的收到各种网站的验证码短信,是手机病毒还是人为恶搞?有这种手机病毒吗?  C++如何使用std::optional?(处理可选值)  如何选择适合PHP云建站的开源框架?  怎么将XML数据可视化 D3.js加载XML  北京网站制作的公司有哪些,北京白云观官方网站?  孙琪峥织梦建站教程如何优化数据库安全?  广州营销型建站服务商推荐:技术优势与SEO优化解析  seo网站制作优化,网站SEO优化步骤有哪些?  常州自助建站工具推荐:低成本搭建与模板选择技巧  在线教育网站制作平台,山西立德教育官网?  如何获取上海专业网站定制建站电话?  如何通过山东自助建站平台快速注册域名?  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  如何基于PHP生成高效IDC网络公司建站源码?  h5在线制作网站电脑版下载,h5网页制作软件?  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  IOS倒计时设置UIButton标题title的抖动问题  香港服务器建站指南:外贸独立站搭建与跨境电商配置流程  做企业网站制作流程,企业网站制作基本流程有哪些?  XML的“混合内容”是什么 怎么用DTD或XSD定义  建站主机SSH密钥生成步骤及常见问题解答?  建站VPS选购需注意哪些关键参数?  相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?  网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?  如何在Golang中使用encoding/gob序列化对象_存储和传输数据  建站之星在线客服如何快速接入解答?  国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?  如何在景安云服务器上绑定域名并配置虚拟主机?  如何在服务器上三步完成建站并提升流量?  建站主机无法访问?如何排查域名与服务器问题  如何配置FTP站点权限与安全设置?  如何通过.red域名打造高辨识度品牌网站?  深入理解Android中的xmlns:tools属性  保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?  教育培训网站制作流程,请问edu教育网站的域名怎么申请?  昆明网站制作哪家好,昆明公租房申请网上登录入口?  深圳网站制作案例,网页的相关名词有哪些?  视频网站制作教程,怎么样制作优酷网的小视频?  如何在橙子建站上传落地页?操作指南详解  如何通过NAT技术实现内网高效建站?  如何在Golang中引入测试模块_Golang测试包导入与使用实践  浅析上传头像示例及其注意事项  西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  韩国服务器如何优化跨境访问实现高效连接?  简单实现Android文件上传  高端企业智能建站程序:SEO优化与响应式模板定制开发  网站制作知乎推荐,想做自己的网站用什么工具比较好? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。