RxSwift学习之Observable的新建、订阅及取消订阅
发布时间 - 2026-01-11 03:20:04 点击率:次前言

我们在前一篇基础之上,本文将会介绍 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代码示例
# 是一个
# 的是
# 只需
# 能在
# 我们可以
# 自定义
# 绑定
# 流进
# 几个
# 如果你
# 文档
# 让人
# 是因为
# 也会
# 多个
# 将会
# 才会
# 会在
# 也很
# 只会
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何获取上海专业网站定制建站电话?
EditPlus中的正则表达式 实战(4)
实例解析angularjs的filter过滤器
Python结构化数据采集_字段抽取解析【教程】
音响网站制作视频教程,隆霸音响官方网站?
JavaScript如何实现错误处理_try...catch如何捕获异常?
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Laravel如何实现API版本控制_Laravel API版本化路由设计策略
如何快速搭建高效WAP手机网站吸引移动用户?
太平洋网站制作公司,网络用语太平洋是什么意思?
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
如何在 Pandas 中基于一列条件计算另一列的分组均值
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
历史网站制作软件,华为如何找回被删除的网站?
大连网站制作公司哪家好一点,大连买房网站哪个好?
青岛网站建设如何选择本地服务器?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
JavaScript中的标签模板是什么_它如何扩展字符串功能
网站制作价目表怎么做,珍爱网婚介费用多少?
微信小程序 HTTPS报错整理常见问题及解决方案
如何在企业微信快速生成手机电脑官网?
如何快速选择适合个人网站的云服务器配置?
桂林网站制作公司有哪些,桂林马拉松怎么报名?
米侠浏览器网页背景异常怎么办 米侠显示修复
Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】
Laravel如何集成Inertia.js与Vue/React?(安装配置)
Java垃圾回收器的方法和原理总结
Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】
Laravel观察者模式如何使用_Laravel Model Observer配置
Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
如何在自有机房高效搭建专业网站?
小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
JavaScript模板引擎Template.js使用详解
WordPress 子目录安装中正确处理脚本路径的完整指南
大学网站设计制作软件有哪些,如何将网站制作成自己app?
七夕网站制作视频,七夕大促活动怎么报名?
LinuxCD持续部署教程_自动发布与回滚机制
Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
网站制作大概多少钱一个,做一个平台网站大概多少钱?
免费视频制作网站,更新又快又好的免费电影网站?
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
php 三元运算符实例详细介绍
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
成都网站制作公司哪家好,四川省职工服务网是做什么用?
Linux后台任务运行方法_nohup与&使用技巧【技巧】
Laravel怎么上传文件_Laravel图片上传及存储配置
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】

