- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章RxSwift学习之Observable的新建、订阅及取消订阅由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
我们在前一篇基础之上,本文将会介绍 RxSwift 中的 Observables 部分.
在 RxSwift 中 Observable 也被称为 Observable Sequence、Sequence、Stream。Observable 会以异步的方式不断的发射事件形成事件流,并且数据也会沿着事件流进行传播。下图是事件流的图像化表示:
其中从左到右的箭头代表时间轴,而三个圆圈则构成了可观察序列。而整个过程会按照从左到右的顺序。另外,事件可能在可观察序列生命周期内的任意时刻被触发.
Observable 生命周期 。
上图中的三个圆圈其实就是 RxSwift 中的 next 事件。除了 next 之外,RxSwift 中还有 completed 和 error 事件,而这两者都意味事件流生命周期的总结.
completed 所表示的正常终结:
error 所表示的异常终结:
在源码中这三类事件的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/// 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
2
3
4
5
6
7
|
// 1
let one = 1
let two = 2
let three = 3
// 2
let observable: Observable<Int> = Observable<Int>.just(one)
|
作为类方法 just 所创建的 Observable 对象只会包含一个元素。但是大多数时候,Observable 对象在其生命周期内会包含多个元素,而创建方法也很简单:
1
|
let observable2 = Observable.of(one, two, three)
|
可能上面的代码会给人一种误导,让人觉得 observable2 中的数据可能是一个数组类型。不过好在我们可以通过下面的代码进行检验:
1
2
3
4
5
6
7
8
9
|
observable2.subscribe(onNext: { element in
print(element)
})
/* 打印结果:
1
2
3
*/
|
而真正创建数组类型变量的方法是:
1
2
3
4
5
6
7
8
|
let observable3 = Observable.of([one, two, three])
observable3.subscribe(onNext: { element in
print(element)
})
/* 打印结果:
[1, 2, 3]
*/
|
上面只是几个常用的 Observable 创建方法,更多的内容可以去查文档和代码.
订阅 Observable 。
在日常 iOS 编程中,通知模式可以说是使用频率相当高的一个设计模式。我们通过 NotificationCenter 实现消息的广播和订阅。下面是一个典型的通知模式代码用于处理 UIKeyboardDidChangeFrame 消息:
1
2
3
4
5
6
|
let observer = NotificationCenter.
default
.addObserver(
forName: .UIKeyboardDidChangeFrame,
object: nil,
queue: nil ) { notification in
// 闭包
}
|
RxSwift 中的订阅操作也非常简单,只需要调用 subscribe 方法就行了。不过与 NotificationCenter 机制不同的是,RxSwift 中每一个订阅都是唯一的并没有一个类似 default 这样的全局单例对象.
更为重要的是,在没有订阅者的时候 Observable 对象不会发送通知。另外, Observable 对象实际上是一个序列,所以订阅操作有点类似于反复调用 Swift 标准库里中迭代器 Iterator 对象 next 函数:
1
2
3
4
5
6
7
8
9
10
11
|
let sequence = 0..<3
var iterator = sequence.makeIterator()
while
let n = iterator.next() {
print(n)
}
/* 打印结果:
0 1 2
*/
|
不过 RxSwift 订阅操作明显比这个来的更直接,并且可以一次实现对 next、error、completed 事件的的处理。一个简单的订阅操作示例:
1
2
3
4
5
6
7
8
9
|
let one = 1
let two = 2
let three = 3
let observable = Observable.of(one, two, three)
observable.subscribe { event in
print(event)
}
|
上面代码的订阅操作非常简单:打印出 observable 声明周期内的所有事件。正常情形下,它的结果如下:
1
2
3
4
|
next(1)
next(2)
next(3)
completed
|
当然,有时候我们可能只是需要 observable 所发射的数据:
1
2
3
4
5
6
7
8
9
10
11
|
observable.subscribe { event in
if
let element = event.element {
print(element)
}
}
/* 打印结果:
1
2
3
*/
|
又或者,我们需要对不同事件区别处理:
1
2
3
4
5
6
7
8
9
|
observable .subscribe(
onNext: { element in
print(element)
},
onCompleted: {
print(
"Completed"
)
}
)
|
取消订阅并消除内存泄漏 。
Observable 对象只有在存在订阅的情形下才会进行数据发送操作,而且会在 error 或 completed 事件触发时结束其生命周期。但是,有时候我们可能需要手动取消订阅并提前终结 Observable 对象的生命.
1
2
3
4
5
|
let observable = Observable.of(
"A"
,
"B"
,
"C"
)
let subscription = observable.subscribe { event in
print(event)
}
|
上面代码非常简单这里就不再细诉了,这里我们直接来看取消订阅的操作。其实,取消订阅的操作非常之简单只需一行代码:
1
|
subscription.dispose()
|
当然,手动对每一个订阅对象进行取消操作显然是一件枯燥的工作。所以 RxSwift 为大家提供了一个更为简单的方案。只需在订阅时调用 .addDisposableTo() 添加一个 DisposeBag 类型对象,我们就能在 DisposeBag 对象销毁时取消所有绑定订阅对象的取消动作.
1
2
3
4
5
6
7
|
let disposeBag = DisposeBag()
Observable.of(
"A"
,
"B"
,
"C"
)
.subscribe {
3 print($0)
}
.addDisposableTo(disposeBag)
|
这里我们之所以需要进行 DisposeBag 对象绑定或者手动调用 dispose() 进行取消订阅操作,是因为如果不这么做的话 Observable 对象在生命周期完结时会存在内存泄漏的问题.
总结 。
本文只是简单的介绍了 Observables 一些常见基础内容。这里还有很多更深入的内容没有介绍,例如:empty 和 never 类型的订阅、使用 Create 实现自定义 Observable 以及 Error 类型的自定义实现。如果你有兴趣的话,我强烈建议你查阅官方文档和代码.
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:https://bignerdcoding.com/archives/51.html 。
最后此篇关于RxSwift学习之Observable的新建、订阅及取消订阅的文章就讲到这里了,如果你想了解更多关于RxSwift学习之Observable的新建、订阅及取消订阅的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我尝试使用 RxSwift 作为依赖项创建一个名为 MyLib 的库,它使用 cocoapod 命令 pod lib create。但是,以下代码不起作用。 import UIKit import M
我是 RxSwift 的新手。很新。通常要在没有 Rx 的情况下链接你,你将下一个函数放在一个完成闭包中。我的同事告诉我改用 flatmap 或我们的 concatmap 版本,但从未给我一个例子。有
我创建了一个使用 RxSwift、RxCocoa 和其他第三方框架的自定义框架。自定义框架正确编译,但当我添加到应用程序时,它崩溃并出现以下错误: dyld: Library not loaded:
我会尽可能简短:我们启动了完整的 RxSwift 应用程序,但我们的协调员开始不知所措,难以维护和扩展,因此我们正在重新设计他们以不使用 RxSwift,现在我们不知道如何使用它们以及保存它们的位置。
我正在使用 RxSwift 和 MVVM 实现一个简单的地址 UITableView。我像这样在我的 View Controller 中创建了一个绑定(bind)。 viewModel.address
ReactiveX.io documentation使用 AnonymousDisposable,它在 RxSwift 2.x 中,但在 RxSwift 3.0 中是一个未解析的标识符。我应该改用什么
我有一个应用程序使用 MVP与 Coordinator图案。 当子协调器发送事件时,我希望我的 AppCoordinator递归调用一个方法,根据一些 SessionState 选择下一个协调器. 该
上下文:我的团队正在开始一个新的中型 Swift 项目(大约 20 MM),我正在考虑在 RxSwift 中开发它.我的一位经理怀疑,他曾经在 上的调试方面有过不好的经历。响应式(Reactive)编
嘿,我在 HackingWithSwift 教程中学到了如何使用 Combine 发出链接的网络请求(请参阅下面的代码)。现在我将使用 RXSwift 构建相同的逻辑,但我不知道如何像在 Combin
我正在尝试进行几个 API 调用并填充领域数据库。 一切正常。但是,当我尝试运行 performSegue()在 subscribe()方法引发异常,通知我不能在后台线程上执行此操作,这是完全合理的。
假设我有 Int 数组: var items = [1, 2, 3, 4, 5] 以及一个接受 Int 参数并基于它发送网络请求的函数: func sendRequest(argument: Int
我有一个文本字段,它有 2 个验证规则:最小数量的字符和字母数字字符。 我希望能够向用户展示他在错误标签中做错了什么,但问题是,如果我将文本字段绑定(bind)到两个规则,它可能会令人毛骨悚然,因为一
我试图在选择表行时在后台执行复杂的计算,但它卡住了 UI。请查看我的代码并告诉我可能有什么问题。 tableView.rx .modelSelected(Sring.self) .fl
我正在尝试构建一个计时器,该计时器从15秒开始,递减计数到0。 事情是,我想根据事件将计时器更新2秒。 到目前为止,这是我尝试做的事情: struct ViewModel { struct I
我正在使用该领域作为后端。使用RxSwift,我可以在DB表中观察到某些列(它跟踪未决状态)。得到事件后,我切换到另一个Serial计划表,以将列的值设置为flatMap块中的Progress状态(返
我对响应式(Reactive)编程很陌生,所以我仍然很难理解它是如何工作的。 我正在尝试做的事情:当用户点击 signUpButton (signUpTrigger) 时,会触发多个 observab
以下是与问题39类似的示例:http://reactivex.io/learnrx/ 我正在尝试将方法调用search(query: String)转换为这些调用的序列。 他们通过创建一个Variab
我有两个 Single 值,它们包含同一对象的数组。我想合并它们并应用 map 并将它们作为单个返回。可能吗? 所以我有这个: func fetchTripList(type: TripType) -
使用 RxSwift,假设我有一个包含整数可观察值的 A 类 class A: { let count: Observable } 以及 A 的可观察对象集合 let data: Observ
我想转换一个我已经完全接收的 ViewModel。该应用程序计算算术表达式。 ViewModel 有两个字符串,一个带有“逻辑”符号,将发送到表达式求值器以获取结果,另一个带有其他符号的“演示”字符串
我是一名优秀的程序员,十分优秀!