RxSwift Observer-观察者

2018-09-21  本文已影响48人  darrenW

我们在之前已经了解了什么是Observer观察者,这篇我们了解一下怎么创建观察者以及特征观察者。

1.在 subscribe 方法中创建

创建观察者最直接的方法就是在Observablesubscribe方法后面描述当事件发生时,需要如何做出响应。举个🌰:

let observable = Observable.of(1,2,3,4,5)
observable.subscribe(onNext: { element in
    print(element)
}, onError: { error in
    print(error)
}, onCompleted: {
    print("completed")
})

运行结果如下:


运行结果.png

2.在bind方法中创建

我们创建一个定时生成索引数的Observable序列,并将索引数不断显示在label标签上
举个🌰:

import UIKit
import RxCocoa
import RxSwift

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
        observable.map{ "当前索引数:\($0)" }
            .bind { [weak self](text) in
                self?.label.text = text
        }.disposed(by: disposeBag)
    }
   
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

运行结果:

bind结果.png
除了以上创建方法外,我们还可以使用其他的方式,比如AnyObserverBinder

3.使用AnyObserver创建观察者

AnyObserver可以用来描叙任意一种观察者

3.1配合subscribe方法使用
let observer: AnyObserver<Int> = AnyObserver { event in
    switch event{
    case .next(let data):
        print(data)
    case .error(let error):
        print(error)
    case .completed:
        print("completed")
    }
}
let observable = Observable.of(1,2,3,4,5)
observable.subscribe(observer)

运行结果如下:


运行结果.png
3.2配合bindTo方法使用
import UIKit
import RxCocoa
import RxSwift

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let observer: AnyObserver<String> = AnyObserver{
            [weak self] event in
            switch event{
            case .next(let text):
                self?.label.text = text
            default:
                break
            }
        }
        let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
        observable.map{"当前索引数:\($0)"}
                .bind(to: observer)
                .disposed(by: disposeBag )
    }
   
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

4. Binder

Binder 主要有以下两个特征:

一旦产生错误事件,在调试环境下将执行fatalError,在发布环境下将打印错误信息
在上面更新label文字的例子中,更好的方式就是使用Binder。理由有二:

import UIKit
import RxCocoa
import RxSwift

class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let observer: Binder<String> = Binder(label){
            (view,text) in
            view.text = text
        }
        let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
        observable.map{ "当前索引数:\($0)"}
                .bind(to: observer)
                .disposed(by: disposeBag)
    }
   
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

下面,我们再去实现另外一段代码:

let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable.map{ $0 % 2 == 0}
        .bind(to: label.rx.isHidden)
        .disposed(by: disposeBag)

此时label会不断的消失、出现。这段代码里我们又操作了什么?查看label.rx.isHiddenisHidden可以发现

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

其实RxCocoa在对许多 UI 控件进行扩展时,就利用Binder将控件属性变成观查者,我们也可以用这种方式来创建自定义的 UI 观察者。

上一篇下一篇

猜你喜欢

热点阅读