【RXSwift】系列二 :Observer创建

Observer创建

观察者 是用来监听事件,然后它需要这个事件做出响应

常见观察者

  • AnyObserver - 任意一种观察者
  • Binder - 特定观察者:比如UI观察者

Observable 与 Observer 之间的关联

  • subscribe(...) - 订阅
  • bind(...) - 绑定
  1. 直接在subscribe中创建

直接在Observable的subscribe方面后面描述当事件发生时,如何作出响应

    func subObserver() {
        let ofSequence = Observable.of(1,2,3)
        _ = ofSequence.subscribe(onNext: { element in
            print(element)
        }, onCompleted: {
            print("completed")
        })
    }

运行结果:

1
2
3
completed
  1. 在bind方法中创建

     func bindObserver() {
         let intervalSequence = Observable.interval(1, scheduler: MainScheduler.instance)
         _ = intervalSequence.bind { element in
             print(element)
         }
     }
    

运行结果:

0
1
2
3
...

3.使用 AnyObserver创建

AnyObserver可以用来描述任意一种观察者,可以配合subscribe和bindTo使用

    func anyObserver() {
        let observer = AnyObserver { event in
            switch event {
            case .next(let data):
                print(data)
                
            case .error(let error):
                print(error)
                
            case .completed:
                print("completed")
                
            }
        }
        let ofSequence = Observable.of(1,2,3)
//        _ = ofSequence.subscribe(observer)
        _ = ofSequence.bind(to: observer)
        
    }

运行结果:

1
2
3
completed
  1. 使用Binder创建

Binder 主要有以下两个特征:

  • 不会处理错误事件
  • 确保绑定都是在给定 Scheduler 上执行(默认 MainScheduler)

相较于 AnyObserver 的大而全,Binder 更专注于特定的场景, 典型的是成为 UI 观察者

一旦产生错误事件,在调试环境下将执行 fatalError,在发布环境下将打印错误信息

    func binderObserver() {
        let observer = Binder(label) { (label,element) in
            print(element)
            label.text = element
        }
        let ofSequence = Observable.of(1,2,3)
        _ = ofSequence.map{"当前值为:\($0)"}
            .subscribe(observer)
    }

运行结果:

当前值为:1
当前值为:2
当前值为:3

RXCocoa中对很多控件做了扩展,就是利用Binder将控件属性变为观察者。

  • UI 控件在 RxCocoa 下某些属性都是被观察者(Observable),都可以发出序列,常见的有
    • 控件的 text 类型是 ControlProperty ,最终遵循 ObservableType协议
    • 按钮的点击 tap 类型是 ControlEvent,最终遵循 ObservableType协议
  • 对于设置 UI 控件的一些 Bool 类型的属性,如可输入,可点击,一般用 Binder (遵循 ObserverType协议) 来生成观察者,对接受的数据条件进行判断是否可以输入、可点击
extension Reactive where Base: UILabel {
    
    /// Bindable sink for `text` property.
    public var text: Binder {
        return Binder(self.base) { label, text in
            label.text = text
        }
    }

    /// Bindable sink for `attributedText` property.
    public var attributedText: Binder {
        return Binder(self.base) { label, text in
            label.attributedText = text
        }
    }
    
}

直接使用
    func rxObserver() {
        let justSequence = Observable.just(1)
        _ = justSequence.map{"当前值为:\($0)"}
            .bind(to: label.rx.text)
    }

其实 RxCocoa 在对许多 UI 控件进行扩展时,就利用 Binder 将控件属性变成观查者

比如 UIControl+Rx.swift 中的 isEnabled 属性便是一个 observer :

UIControl+Rx

/// 按钮是否可点击 button.rx.isEnabled:
extension Reactive where Base: UIControl {
    public var isEnabled: Binder {
        return Binder(self.base) { control, value in
            control.isEnabled = value
        }
    }
}

UILabel+Rx

/// label 的当前文本 label.rx.text
extension Reactive where Base: UILabel {
    public var text: Binder {
        return Binder(self.base) { label, text in
            label.text = text
        }
    }
}

UIView+Rx

extension Reactive where Base: UIView {
    public var isHidden: Binder {
        return Binder(self.base) { (view, hidden) in
            view.isHidden = hidden
        }
    }
}

你可能感兴趣的:(【RXSwift】系列二 :Observer创建)