RxSwift核心之辅助类型

作者: __Mr_Xie__ | 来源:发表于2019-10-09 16:41 被阅读0次

    前言

    框架里面定义了一些 辅助类型,它们既是 可监听序列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, 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 控件属性的,它具有以下特征:

    • 不会产生 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开发者进阶,直接留言,留言必回。

    相关文章

      网友评论

        本文标题:RxSwift核心之辅助类型

        本文链接:https://www.haomeiwen.com/subject/hfnwpctx.html