RxSwift Learning-04-シーケンスの作成、サブスクリプション、および破棄

一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して4日目です。クリックしてイベントの詳細をご覧ください以前にRxSwiftのコアロジックを学習しましたObservableが、シーケンスを作成、サブスクライブ、および破棄する方法は何ですか?この記事では主にその方法を紹介します。

1.オブザーバールの作成

の場合Observale、ガラスビーズが常に流れるチューブのように、すべてがシーケンスであることが理解できます。これらは、観察者が変化を観察し、対応する変化を起こすたびに発生する変化を表しています。

image.png

それからObservale私達の作成のために私達は通常create作成します

1.1作成の作成

// 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.2bindToバインディング

シーケンス绑定を別のオブザーバーに置くことができます

// 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)

        
    }
复制代码

もちろん、処理を直接バインドして、上記と同じ効果をラベルに表示することもできます。

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.3AnyObserverの作成

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)

        

        

    }
复制代码

私たちのシーケンスは直接サブスクライブすることができます。

  • バインダー

これは、バインダーの統一された一般的なオブザーバーであり、AnyObserverバインダーには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つずつ見ていきましょう。

1.4.1空

空のシーケンス:完全なイベントのみを受信できる空のシーケンスを作成するために使用されます

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)
     

    }
复制代码

完全に印刷し、直接廃棄します。信号を送信せずに直接完了したことを示します。

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