美文网首页iOS-Rx
RxSwift二:Subject

RxSwift二:Subject

作者: 狂奔的胖蜗牛 | 来源:发表于2018-04-23 13:42 被阅读12次

    RxSwift练习:https://github.com/flywo/RxSwiftPractice

    Subject

    Subject既是被观察者,又是观察者。有如下四种类型:
    1.PublishSubject:只会发送最新的事件
    2.BehaviorSubject:发送订阅前一次事件或初始化事件以和后续事件
    3.ReplaySubject:发送订阅前指定缓存的事件
    4.Variable:BehaviorSubject的封装

    PublishSubject

    //创建主题
    let subject = PublishSubject<String>()
    //发布事件,此时不会有任何反应,因为没人订阅该主题
    subject.onNext("1")
    //订阅主题,此时也不会有任何反应,因为发布事件在订阅主题前面
    let subscriptionOne = subject.subscribe {print($0)}
    //此时发布事件,就有反应了
    subject.onNext("2")
    
    ////PublishSubject////
    let subscriptionTwo = subject.subscribe { event in
        print("2", event.element ?? event)
    }
    subject.onNext("3")
    //停止订阅one
    subscriptionOne.dispose()
    //此时不会再有one的打印
    subject.onNext("4")
    //一旦发送了completed/error等stop事件,则后续next事件不会再次发送,但是会继续发送重复发送停止事件,即completed/error事件
    subject.onCompleted()
    subject.onNext("5")
    subscriptionTwo.dispose()
    let disposeBag = DisposeBag()
    subject.subscribe {
        print("3", $0.element ?? $0)
        }.disposed(by: disposeBag)
    subject.onNext("?")
    

    执行结果如下:

    next(2)
    next(3)
    2 3
    2 4
    2 completed
    3 completed
    

    需要注意的点:
    1.发送.completed事件,会终止被观察者队列
    2.即使给队列添加新的订阅,任然不会发送.next事件,因为队列已经被终止
    3.使用完毕后,一定记得取消订阅
    4.即使被终止了,不会发送后续.next事件,但是终止的completed事件还是会发送

    BehaviorSubject

    enum MyError: Error {
        case anError
    }
    func customPrint<T: CustomStringConvertible>(label: String, event: Event<T>) {
        //打印元素,如果不存在就打印错误,如果不存在就打印事件
        print(label, event.element ?? event.error ?? event)
    }
    
    //由于会发送上一次事件,所以必须要初始化
    let subject = BehaviorSubject(value: "Initial value")
    let disposeBag = DisposeBag()
    subject.onNext("X")
    //会将X打印出来
    subject.subscribe {
        customPrint(label: "1->", event: $0)
        }.disposed(by: disposeBag)
    subject.onNext("Y")
    subject.onError(MyError.anError)
    subject.subscribe {
        customPrint(label: "2->", event: $0)
        }.disposed(by: disposeBag)
    subject.onNext("Z")
    

    打印:

    1-> X
    1-> Y
    1-> anError
    2-> anError
    

    ReplaySubject

    //指定了buffer为2
    let subject = ReplaySubject<String>.create(bufferSize: 2)
    let disposeBag = DisposeBag()
    subject.onNext("1")
    subject.onNext("2")
    subject.onNext("3")
    subject.subscribe {
        customPrint(label: "1->", event: $0)
        }.disposed(by: disposeBag)
    //1不会被打印,因为已经超过了buffer
    subject.subscribe {
        customPrint(label: "2->", event: $0)
        }.disposed(by: disposeBag)
    
    subject.onNext("4")
    subject.onError(MyError.anError)
    //添加错误,依旧会返回上两个事件
    //            subject.dispose()一般来说,不需要主动销毁订阅,让其自动管理就好
    subject.subscribe {
        customPrint(label: "3->", event: $0)
        }.disposed(by: disposeBag)
    

    打印:

    1-> 2
    1-> 3
    2-> 2
    2-> 3
    1-> 4
    2-> 4
    1-> anError
    2-> anError
    3-> 3
    3-> 4
    3-> anError
    

    Variable

    //可以明确类型Variable<String>("")
    let variable = Variable("Initial value")
    let disposeBag = DisposeBag()
    //对value进行赋值,则等价于调用了onNext
    variable.value = "New initial value"
    //通过asObservable可以获得被封装了的BehaviorSubject.
    //不需要手动的completed
    variable.asObservable().subscribe {
        customPrint(label: "1->", event: $0)
        }.disposed(by: disposeBag)
    
    //不能variable添加error和completed
    variable.value = "1"
    variable.asObservable().subscribe {
        customPrint(label: "2->", event: $0)
        }.disposed(by: disposeBag)
    variable.value = "2"
    

    打印:

    1-> New initial value
    1-> 1
    2-> 1
    

    相关文章

      网友评论

        本文标题:RxSwift二:Subject

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