RxSwift学习-04-序列的创建,订阅和销毁

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。 我们之前学习了RxSwift的核心逻辑,那么对于Observable序列的创建,订阅,销毁有哪些方式呢?本文主要介绍他们的方式。

1. Observale创建

对于Observale来说,我们可以理解为万物皆序列,就像一个管子里面一直流着玻璃珠,这些代表着每次发生的变化 我们观察者观察到变化做出对应的改变。

image.png

那么对于Observale的创建我们通常通过create创建

1.1 create创建

// MARK: - create创建

    

    func create(){

        

        let ob = Observable<String>.create { (observer) -> Disposable in

            

            observer.onNext("hello")

            

            return Disposables.create()

            

        }

        

        ob.subscribe(onNext: {(str) in

            

            print("str:\(str)")

        }).disposed(by: disposeBag) 

    }
复制代码

1.2 bindTo绑定

我们可以把我们的序列绑定到另一个观察者上

// MARK: - bindTo绑定



    func bind(){

        

        let timer = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)

        
        timer.map{"当前计时器数:\($0/3600):\($0/60):\($0%60)"}

          .bind(to: self.label.rx.text)

            .disposed(by: disposeBag)

        
    }
复制代码

当然我们也可以直接绑定处理,显示在label上和上面效果一样

let timer = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
timer.map{"当前计时器数:\($0/3600):\($0/60):\($0%60)"}

            .bind{ [weak self](str) in


                self?.label.text = str


            }.disposed(by: disposeBag)
复制代码

1.3 AnyObserver创建

AnyObserver 表示是任意一种观察者,我们可以定义它的闭包回调eventHandler

func anyObserver() {

        

        let observer : AnyObserver<String> = AnyObserver { (event) in

            

            switch event{

            case .next(let str):

                print(str)

            case .error(let error):

                print(error)

            case .completed:

                print("完成")

            }

        }

        

        let observable = Observable.of("1","2","3")

        

        observable.subscribe(observer)

            .disposed(by: disposeBag)

        

        

    }
复制代码

我们的序列直接订阅即可。

  • Binder

对于AnyObserver来说是一个统一的笼统的观察者,而对于Binder有2个特征:

  • 不处理错误事件
  • 确保绑定在指定的Scheduler执行,默认是MainScheduler

对于在UI的事件我们通常在主线程进行更新,因此我们可以使用binder类型的观察者进行bind

// MARK: - Binder

    

    func binder() {

        

        let observable = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.asyncInstance)

        

        let binder:Binder<String> = Binder(label) {

            (lab,text) in

            lab.text = text

        }

        observable.map{"第:\($0)个"}

            .subscribe(binder)

            .disposed(by: disposeBag)

        

    }
复制代码

当然我们也可以使用 bindto

observable.map{"第:\($0)个"}

//            .subscribe(binder)

            .bind(to: binder)

            .disposed(by: disposeBag)
复制代码

1.4 工厂方法

在RxSwift中作者为我们提供了一些快捷的工厂方法,下面我们一一看下:

1.4.1 empty

空序列:用于创建一个空序列,只能接受到complete事件

func empty() {

        

        let emptyObservable = Observable<Int>.empty()

        emptyObservable.subscribe { (num) in

            print(num)

        } onError: { (error) in

            print("error")

        } onCompleted: {

            print("complete")

        } onDisposed: {

            print("dispose")

        }.disposed(by: disposeBag)
     

    }
复制代码

直接打印 completedispose。说明没有发送信号就直接完成了。

image.png

在subscribe的时候直接observer.on(.completed)完成了

1.4.2 just

just : 构建只有一个默认值来初始化,该Observable队列只有一个元素,订阅完成直接发送complete

func just() {

        

        let arr = [1,2,3]

        Observable<[Int]>.just(arr)//单个元素

            .subscribe { (event) in

                print(event)

            }.disposed(by: disposeBag)

        

        Observable<[Int]>.just(arr).subscribe { arr in

            print(arr)

        } onError: { error in

            print(error)

        } onCompleted: {

            print("complete")

        } onDisposed: {

            print("dispose")

        }.disposed(by: disposeBag)
        
    }
复制代码

image.png

订阅的时候直接发送初始化的元素,以及完成事件

1.4.3 of

of: 相对一just单个元素的序列,of则可以表示多个元素序列

func of() {

        

        //多个元素

        let observable = Observable<Int>.of(1,2,3,4)

        observable.subscribe { (num) in

            print(num)

        } onError: { error in

            print(error)

        } onCompleted: {

            print("complete")

        } onDisposed: {

            print("dispose")

        }.disposed(by: disposeBag)

        // 字典

        Observable<[String:Any]>.of(["name":"fish","age":18],["name":"fishMan","age":18]).subscribe { (dic) in

            print(dic["name"]!)

        } onError: { error in

            print(error)

        } onCompleted: {

            print("complete")

        } onDisposed: {

            print("dispose")

        }.disposed(by: disposeBag)

        

        // 数组

        

        Observable<[Int]>.of([1,2,3]).subscribe { (arr) in

            print(arr[0])

        } onError: { error in

            print(error)

        } onCompleted: {

            print("complete")

        } onDisposed: {

            print("dispose")

        }.disposed(by: disposeBag)

    }
复制代码

我们可以对于element可以是数组或者字典作为序列的元素

image.png

订阅流程也是通过sink 调用run,通过迭代器进行遍历发送信号。

1.4.4 from

form: 从集合中获取序列:数组,集合,set 获取序列

  • 有可选项处理
  • 更安全
func from() {

        

        Observable<[String:Any]>.from(optional: ["name":"fish","age":18])

            .subscribe { (dic) in

                print(dic["age"] as Any)

            }  onError: { error in

                print(error)

            } onCompleted: {

                print("complete")

            } onDisposed: {

                print("dispose")

            }.disposed(by: disposeBag)

    }

复制代码

image.png

订阅的时候进行判断元素是否存在,发送observer.on(.next(element))序列 否则 随即自动observer.on(.completed)完成序列发送

image.png

1.4.5 deferred

deferred : 用于延迟Observable序列的初始化,返回一个可观察序列,该序列在新观察者订阅时调用指定的工厂函数

func deferred() {

    

        var isEven = true

        

        Observable<Int>.deferred { () -> Observable<Int> in



            isEven = !isEven

            

            if isEven {

        

                return Observable<Int>.of(2,4,6,8,10)

                

            }else{

                

                return Observable<Int>.of(1,3,5,7,9)

            }

        }.subscribe(onNext: {print($0)})

            .disposed(by: disposeBag)
        

    }
复制代码

我们相当于外界可以控制我们想要的初始化,比如我们登陆和注册页面都是类似的,但是请求的接口不同,我们就可以在外面做出相对的判断,选择对应的注册接口或者登陆接口序列进行初始化订阅,从而减少我们的逻辑判断

image.png

在订阅的时候通过observableFactory工厂方法去创建对应序列,没有的话发送error事件。

1.4.6 rang

range:生成指定范围内的可观察整数序列

_ =  Observable.range(start: 3, count: 6)

            .subscribe(onNext: {print($0)})

            .disposed(by: disposeBag)

复制代码

定义:

image.png

run的时候,小于我们的count则继续发送递增的Int值。

image.png

1.4.7 generate

该方法创建一个只有当提供的所有的判断条件都为 true 的时候,才会给出动作的Observable序列。 初始值给定 然后判断条件1 再判断条件2 会一直递归下去,直到条件1或者条件2不满足 类似 数组遍历循环

Observable.generate(initialState: 0,

                            condition: {$0<10},

                            iterate: {$0+3})

        .subscribe { (num) in

            print(num)

        } onError: { error in

            print(error)

        } onCompleted: {

            print("complete")

        } onDisposed: {

            print("dispose")

        }.disposed(by: disposeBag)
复制代码

运行结果

image.png

数组操作

image.png

实现原理

image.png

condition满足的时候才会发送序列信号,同时通过迭代器iterate进行迭代操作,下次进入的时候判断condition是否满足,不满足发送完成信号

1.4.8 timer

对于定时器我们可以返回一个指定的调度线程

print("start")

        /*

         第一个参数dueTime表示 多少时间后开始计时

         第二个参数period表示 定时器间隔的时间是多少

         第三个表示定时器序列所在的线程

         */

        Observable<Int>.timer( DispatchTimeInterval.seconds(2), period: DispatchTimeInterval.seconds(1), scheduler: MainScheduler.asyncInstance)

            .subscribe { (time) in

                print(time)

            } onError: { (error) in

                print(error)

            } onCompleted: {

                print("completed")

            } onDisposed: {

                print("disposed")

            }.disposed(by: disposeBag)
复制代码

没有指定period时间间隔 默认就会发送一次

image.png

类似的工厂方法,会判断是否存在时间间隔,没有的话表示是一次性的

image.png

对于一次性的直接发送默认0数字结束序列

image.png

对于有时间间隔的,则不断累加定义的间隔进行发送信号

image.png

1.4.9 interval

interval 和定时器类似返回一个可观察序列,该序列在每个周期之后生成一个值,使用指定的调度程序运行计时器并发送观察者消息。

Observable<Int>.interval( DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)

            .subscribe { (time) in

                print(time)

            } onError: { (error) in

                print(error)

            } onCompleted: {

                print("completed")

            } onDisposed: {

                print("disposed")

            }.disposed(by: disposeBag)

复制代码

对于interval还是走的是timer的定时方法,只是序列的element确定是Integer类型。

image.png

1.4.10 repeatElement

通过repeatElement 生成的序列无限重复的给观察者发送

Observable<Int>.repeatElement(2)

            .subscribe { (time) in

                print(time)

            } onError: { (error) in

                print(error)

            } onCompleted: {

                print("completed")

            } onDisposed: {

                print("disposed")

            }.disposed(by: disposeBag)
复制代码

可以发现不断递归发送我们定义的element元素

image.png

1.4.11 error

生成一个只发送error事件的可观察序列

Observable<Any>.error(NSError.init(domain: "networkError", code: 400,userInfo: ["message":"网络错误"]))

            .subscribe { (element) in

            print(element)

        } onError: { (error) in

            print(error)

        }  onCompleted: {

            print("completed")

        } onDisposed: {

            print("disposed")

        }.disposed(by: disposeBag)

复制代码

只会发送error事件

image.png

1.4.11 never

该方法创建一个永远不会发出 Event(也不会终止)的 Observable 序列。

Observable<Int>.never()

            .subscribe { (num) in

                print(num)

            } onError: { (error) in

                print(error)

            } onCompleted: {

                print("completed")

            } onDisposed: {

                print("disposed")

            }.disposed(by: disposeBag)


复制代码

不会发生任何事件

image.png

2. 订阅

对于订阅我们通常2种方式

  • 订阅制定的事件
let observable = Observable<Int>.of(1,2,3,4)

        observable.subscribe { (num) in

            print(num)

        } onError: { error in

            print(error)

        } onCompleted: {

            print("complete")
``
        } onDisposed: {

            print("dispose")

        }.disposed(by: disposeBag)
复制代码

当然我们也可以指定我们关注的事件回调

//订阅指定事件

        observable.subscribe(onNext:{(num) in

            print(num)

        }).disposed(by: disposeBag)
复制代码

或者订阅所有事件

//订阅所有事件

        observable.subscribe { (event) in

            print(event)

        }.disposed(by: disposeBag
复制代码

3. 销毁

通常我们使用垃圾袋DisposeBag()来管理序列比如我们定时器中,重新定义dispaosBag

Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)

            .subscribe { [weak self] (num) in

                

                print(num)

                if (num == 4){

                    self!.disposeBag = DisposeBag()//倾倒之前的垃圾袋

                }

            } onError: { (error) in

                print(error)

            } onCompleted: {

                print("completed")

            } onDisposed: {

                print("disposed")

            }.disposed(by: disposeBag)

复制代码

执行结果:

image.png

我们的序列就伴随我们之前定义的disposebag销毁。

  • 主动发送销毁
let ob =  Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)

    

        let subscirber = ob.subscribe {  (num) in

            

            print(num)

            if (num == 4){

                

            }

        } onError: { (error) in

            print(error)

        } onCompleted: {

            print("completed")

        } onDisposed: {

            print("disposed")

        }

        

        subscirber.dispose()
复制代码

4. 总结

对于序列的创建和订阅,销毁。我们更多的关注序列的创建方式,通过工厂方法可以快速便捷的创建我们合适的序列,而对于订阅通常没有特别的要求,根据自己的选择是否订阅完整的事件。销毁我们可以通过主动调用或者更换垃圾袋做到销毁的目的。

猜你喜欢

转载自juejin.im/post/7082606969478971423