前言
框架里面定义了一些 辅助类型
,它们既是 可监听序列
( Observable
)也是 观察者
( Observer
)。如果你能合适的应用这些 辅助类型
,它们就可以帮助你更准确的描述事物的特征。
辅助类型分为
PublishSubject
AsyncSubject
ReplaySubject
BehaviorSubject
ControlProperty
PublishSubject
PublishSubject
将对观察者发送订阅后产生的元素,而在订阅前发出的元素将不会发送给观察者,示例代码如下:
func test() {
let disposeBag = DisposeBag()
let publicSubject = PublishSubject<Int>()
publicSubject.onNext(1)
publicSubject.subscribe { (e) in
print(e.element ?? 0)
}.disposed(by: disposeBag)
publicSubject.onNext(2)
publicSubject.onNext(3)
}
打印结果:
2
3
AsyncSubject
AsyncSubject
将在源 Observable
产生完成事件后,发出最后一个元素(仅仅只有最后一个元素),如果源 Observable
没有发出任何元素,只有一个完成事件,示例代码如下:
func test() {
let disposeBag = DisposeBag()
let asyncSubject = AsyncSubject<String>()
asyncSubject.subscribe { (e) in
print(e)
}.disposed(by: disposeBag)
asyncSubject.onNext("A")
asyncSubject.onNext("B")
asyncSubject.onNext("C")
asyncSubject.onCompleted()
}
打印结果:
next(C)
completed
如果源 Observable
因为产生了一个 error
事件而中止, AsyncSubject
就不会发出任何元素,而是将这个 error
事件发送出来,示例代码如下:
enum MyError: Error {
case A
case B
var errorType: String {
switch self {
case .A:
return "I am error A"
case .B:
return "I am error B"
}
}
}
func test() {
let disposeBag = DisposeBag()
let asyncSubject = AsyncSubject<String>()
asyncSubject.subscribe { (e) in
print(e)
}.disposed(by: disposeBag)
asyncSubject.onNext("🐼")
asyncSubject.onNext("🐼🐼")
asyncSubject.onNext("🐼🐼🐼")
asyncSubject.onError(MyError.A)
asyncSubject.onCompleted()
}
打印结果:
error(A)
ReplaySubject
ReplaySubject
将对观察者发送全部的元素,无论观察者是何时进行订阅的。
这里存在多个版本的 ReplaySubject
,有的只会将最新的 n 个元素发送给观察者,有的只会将 限制时间段内
最新的元素发送给观察者,示例代码如下:
func test() {
let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 2)
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
subject.subscribe { (e) in
print(e.element ?? "")
}.disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
subject.onNext("C")
}
打印结果:
2
3
A
B
C
注:如果把 ReplaySubject
当作观察者来使用,注意不要在多个线程调用 onNext
, onError
或 onCompleted
。这样会导致无序调用,将造成意想不到的结果。
BehaviorSubject
当观察者对 BehaviorSubject
进行订阅时,它会将源 Observable
中 最新的元素
发送出来(如果不存在最新的元素,就发出默认元素)。然后将随后产生的元素发送出来,示例代码如下:
func test() {
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "🔴")
subject.onNext("1")
subject.onNext("2")
// 订阅时,如果不存在最新的元素,就发出默认元素;如果存在最新的元素,就发出最新元素,不发默认元素
subject.subscribe { (e) in
print("(1) \(e.element ?? "")")
}.disposed(by: disposeBag)
subject.onNext("B")
subject.onNext("C")
subject.subscribe { (e) in
print("(2) \(e.element ?? "")")
}.disposed(by: disposeBag)
subject.onNext("D")
subject.onNext("E")
}
打印结果:
(1) 2
(1) B
(1) C
(2) C
(1) D
(2) D
(1) E
(2) E
注:如果源 Observable
因为产生了一个 error
事件而中止, BehaviorSubject
就不会发出任何元素,而是将这个 error
事件发送出来。
ControlProperty
ControlProperty
专门用于描述 UI
控件属性的,它具有以下特征:
- 不会产生
error
事件 - 一定在
MainScheduler
订阅(主线程订阅) - 一定在
MainScheduler
监听(主线程监听) - 共享附加作用
注:ControlProperty
就不仔细介绍了,如果想要详细了解,参考这篇 文章,这里举一个简单的例子,示例代码如下:
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let disposeBag = DisposeBag()
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var lable: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
textField.rx.text.bind(to: lable.rx.text).disposed(by: disposeBag)
}
}
代码显示效果:让一个 textField
里输入内容实时地显示在另一个 label
上,即前者作为被观察者,后者作为观察者。
运行结果如下图:
Author
如果你有什么建议,可以关注我的公众号:iOS开发者进阶
,直接留言,留言必回。
网友评论