RxSwift学习(三)— Observer、Binder、Subjects、BehaviorRelay

observer(观察者)

观察者(Observer)的作用就是监听事件,然后对这个事件做出响应。或者说任何响应事件的行为都是观察者

观察者的创建有以下几种

  • subscribebinder的方法中创建观察者
  • 使用 AnyObserver 创建观察者
  • 使用 Binder 创建观察者
    我们一般
subscribebind方法中直接创建观察者
  • subscribe中直接创建
  • 创建观察者最直接的方法就是在 Observablesubscribe 方法后面描述当事件发生时,需要如何做出响应。
  • 比如下面的样例,观察者就是由后面的 onNext,onError,onCompleted 这些闭包构建出来的
		Observable<String>.of("Json","XML")
            .subscribe { (element) in
                print("---of---\(element)")
            } onError: { (error) in
                print(error)
            } onCompleted: {
                print("completed")
            } onDisposed: {
                print("disposed")
            }

onNext,onError,onCompleted 这些就是不同的观察者

  • bind中直接创建,主要用于绑定各种控件
		let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
 
        observable
            .map { "当前索引数:\($0 )"}
            .bind { [weak self](text) in
                //收到发出的索引数后显示到label上
                self?.label.text = text
            }
            .disposed(by: disposeBag)

这种方式label只能处理Next的事件,而且刷新UI只能在主线程里面刷新

使用 AnyObserver 创建观察者

AnyObserver可以用来描述任何一种观察者,我们可以配合subcribebind(to)使用

  • 配合subcribe使用:
// 观察者
        let observer: AnyObserver<String> = AnyObserver{event in
            switch event {
            case .next(let element):
                print(element)
            case .error(let error):
                print("错误:\(error)")
            case .completed:
                print("completed")
            }
        }
        
        // 创建观察序列
        let observable = Observable.of("JSON","XML")
        observable.subscribe(observer)
        // JSON
        // XML
        // completed
  • 配合bind(to)使用
		//创建观察者
        let observer: AnyObserver<String> = AnyObserver { (envnt) in
            switch envnt {
            case .next(let title):
                // 把数据绑定到按钮上
                self.TestButton.setTitle(title, for: .normal)
            default:
                break
            }
        }
        // 序列
        let observable = Observable.of("测试")
        _ = observable.bind(to: observer)
使用 Binder 创建观察者

一般在特定的场景下会使用binder创建观察者

binder有两大特征:

  • 不会处理错误事件
  • 确保绑定都是在给定 Scheduler 上执行(默认 MainScheduler
//创建 binder 观察者
        let binderObserver: Binder<String> = Binder(self.testTextField) { (view, value) in
            view.text = value
        }
        
        // 序列
        let observable = Observable.of("测试")
        _ = observable.bind(to: binderObserver)

binder一般结合控件使用,在RxCocoa里面运用较多,如:

// 为 UIControl 添加一个扩展
extension Reactive where Base: UIControl {
    public var isEnabled: Binder<Bool> {
        return Binder(self.base) { control, value in
            control.isEnabled = value
        }
    }
}



//Observable序列(每隔1秒钟发出一个索引数)
// 用 button.rx 把isEnabled 和事件关联起来
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
    .map { $0 % 2 == 0 }
    .bind(to: button.rx.isEnabled)
    .disposed(by: disposeBag)

Subjects 介绍

  • 有时我们希望 Observable 在运行时能动态地“获得”或者说“产生”出一个新的数据,再通过 Event 发送出去。这时候我们就可以用Subjects来实现。
  • 比如:订阅一个输入框的输入内容,当用户每输入一个字后,这个输入框关联的 Observable 就会发出一个带有输入内容的 Event,通知给所有订阅者。
  • Subjects 即使订阅者,又是观察者(observer)

因为subjects能够动态的接收新值,所以说他是订阅者
因为当subjects有了新的值之后,就会通过 Event 将新值发出给他的所有订阅者,所以说他是observer

  • Subjects常用的方法有:
  • onNext(:):该方法相当于 subject 接收到一个.next 事件。
  • onError(:):该方法相当于 subject 接收到一个.error 事件。
  • onCompleted()该方法相当于 subject 接收到一个 .completed 事件。
  • Subjects有四种格式:PublishSubjectBehaviorSubjectReplaySubjectBehaviorRelay

相同点:

  • 他们都是 Observable,他们的订阅者都能收到他们发出的新的 Event
  • 在发出..complete.error事件以后,就会终结,就不再发出Event事件了
  • 对于那些在 Subjects 终结后再订阅他的订阅者,也能收到 subject 发出的一条 .complete.errorevent,告诉这个新的订阅者它已经终结了

不同点

  • 当一个新的订阅者刚订阅它的时候,能不能收到 Subject 以前发出过的旧 Event,如果能的话又能收到多少个。
PublishSubject
  • PublishSubject 是最普通的 Subject,它不需要初始值就能创建。
  • PublishSubject 的订阅者从他们开始订阅的时间点起,可以收到订阅后 Subject 发出的新 Event,而不会收到他们在订阅前已发出的 Event
let publish = PublishSubject<String>()
        publish.onNext("A") // A 在订阅之前赋值  不会被打印
        publish.subscribe { (event) in
            print(event.element)
        }.disposed(by: disposeBag)
        publish.onNext("B")
        
        //print B
BehaviorSubject
  • BehaviorSubject需要通过一个默认初始值来创建。
  • 当一个订阅者来订阅它的时候,这个订阅者会立即收到 BehaviorSubjects 上一个发出的 event。之后就跟正常的情况一样,它也会接收到 BehaviorSubject 之后发出的新的 event
		// 需要初始值
        let behavior = BehaviorSubject<String>(value: "A")
        behavior.subscribe { (event) in
            print(event.element)
        }.disposed(by: disposeBag)
        behavior.onNext("B")
        
        //print A B
ReplaySubject
  • ReplaySubject 在创建时候需要设置一个 bufferSize,表示它对于它发送过的 event 的缓存个数。
  • 比如一个 ReplaySubjectbufferSize 设置为 2,它发出了 3 个 .nextevent,那么它会将后两个(最近的两个) event 给缓存起来。此时如果有一个 subscriber 订阅了这个ReplaySubject,那么这个 subscriber 就会立即收到前面缓存的两个 .nextevent
  • 如果一个 subscriber 订阅已经结束的 ReplaySubject,除了会收到缓存的 .nextevent 外,还会收到那个终结的 .error 或者 .completeevent
 //创建一个bufferSize为2的ReplaySubject
        let subject = ReplaySubject<String>.create(bufferSize: 2)
         
        //连续发送3个next事件
        subject.onNext("A")
        subject.onNext("B")
        subject.onNext("C")
         
        // 第1次订阅subject
        // 打印最近两次的事件
        subject.subscribe { event in
            print("第1次订阅:", event)
        }.disposed(by: disposeBag)
        //第1次订阅: next(B)
        //第1次订阅: next(C)
        
        //再发送1个next事件
        subject.onNext("D")
       // 第1次订阅: next(B)
       // 第1次订阅: next(C)
       // 第1次订阅: next(D)
//         
//        //第2次订阅subject
        // 打印缓存的最近两次的事件
        subject.subscribe { event in
            print("第2次订阅:", event)
        }.disposed(by: disposeBag)
    
       // 第1次订阅: next(B)
       // 第1次订阅: next(C)
       // 第1次订阅: next(D)
       // 第2次订阅: next(C)
        //第2次订阅: next(D)
//         
        //让subject结束
        // 打印完成的事件
        subject.onCompleted()
        // 第1次订阅: next(B)
        // 第1次订阅: next(C)
        // 第1次订阅: next(D)
        // 第2次订阅: next(C)
        // 第2次订阅: next(D)
        // 第1次订阅: completed
        // 第2次订阅: completed
        
        //第3次订阅subject
        // 打印最近的两次缓存事件和完成事件
        
        subject.subscribe { event in
            print("第3次订阅:", event)
        }.disposed(by: disposeBag)
        
        // 第1次订阅: next(B)
        // 第1次订阅: next(C)
        // 第1次订阅: next(D)
        // 第2次订阅: next(C)
        // 第2次订阅: next(D)
        // 第1次订阅: completed
        // 第2次订阅: completed
        
        // 第3次订阅: next(C)
        // 第3次订阅: next(D)
        // 第3次订阅: completed
BehaviorRelay
  • BehaviorRelay 是作为Variable 的替代者出现的。它的本质其实也是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建。
  • BehaviorRelay 具有 BehaviorSubject的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event
  • BehaviorSubject 不同的是,不需要也不能手动给 BehaviorReply 发送 completed 或者 error 事件来结束它(BehaviorRelay 会在销毁时也不会自动发送 .complete 的 event)。
  • BehaviorRelay 有一个 value 属性,我们通过这个属性可以获取最新值。而通过它的 accept() 方法可以对值进行修改
//创建一个初始值为包含一个元素的数组的BehaviorRelay
        let subject = BehaviorRelay<[String]>(value: ["1"])
                 
        //修改value值
        subject.accept(subject.value + ["2"])
                 
        //第1次订阅
        subject.asObservable().subscribe {
            print("第1次订阅:", $0)
        }.disposed(by: disposeBag)
        //第1次订阅:  next(["1", "2"])
        //修改value值
        subject.accept(subject.value + ["3"])
        //第1次订阅:  next(["1", "2", "3"])
        
        //第2次订阅
        subject.asObservable().subscribe {
            print("第2次订阅:", $0)
            }.disposed(by: disposeBag)
        //第2次订阅:  next(["1", "2", "3"])

        //修改value值
        subject.accept(subject.value + ["4"])
        //第2次订阅:  next(["1", "2", "3","4"])
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值