iOS学习开发iOS开发iOS开发者进阶

RxSwift核心之辅助类型

2019-10-09  本文已影响0人  __Mr_Xie__

前言

框架里面定义了一些 辅助类型,它们既是 可监听序列Observable )也是 观察者Observer )。如果你能合适的应用这些 辅助类型,它们就可以帮助你更准确的描述事物的特征。

辅助类型分为

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, onErroronCompleted。这样会导致无序调用,将造成意想不到的结果。

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 控件属性的,它具有以下特征:

注: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开发者进阶,直接留言,留言必回。

上一篇 下一篇

猜你喜欢

热点阅读