Disposables


Disposablesとは?


これは
  • の観測可能な伝達方法ではない.
  • を使用したsubscribeメソッドからパラメータ記憶モジュールが受信されると、観測性に関連するすべてのリソースが無効になった後に呼び出されます.
  • subscribe(onNext: ((Int) -> Void)?,
                onError: ((Error) -> Void)?,
                onCompleted:(() -> Void)?,
                onDisposed: (() -> Void)?
                )
    前の投稿では、subscribeを呼び出す方法が2つあります.
    // # 1
    Observable.from([1,2,3])
        .subscribe { element in
        print("Next",element)
    } onError: { error in
        print("Error",error)
    } onCompleted: {
        print("Completed")
    } onDisposed: {
        print("Disposed")
    }
    
    // # 2
    Observable.from([1,2,3])
        .subscribe{
            print($0)
        }
    この2つのプログラムを実行すると、次の結果が出力されます.

    比較結果、
  • #1発Disposed,
  • #2はDisposeを呼び出していません.
  • もしそうであれば、DispostedメソッドはObservableに関連するすべてのリソースが無効になった後に呼び出されますが、2はObservableに関連するすべてのリソースを無効にしていませんか?


    とにかく#1と#2は解除されましたㅋㅋ
  • Observableが完全な方法またはエラーイベントで終了すると、関連リソースは自動的に閉じられます.
    では疑問点です.
  • Dispostedメソッドは、Observableのすべてのリソースが無効になったときに呼び出されるやつですが、なぜ完了またはエラーイベントが終了した後にリソースが無効になったときに呼び出されないのですか?
  • の理由は、Disposedが観測可能な方法(Event)ではないためである.
    (観測可能な方法は、Next、Completed、Errorの3つ)
  • #1でDispostedメソッドを呼び出す理由は、onDisposedパラメータがエンクロージャを提供し、リソースが解放されたときに自動的に呼び出されるためである.
    (#2にはこのような操作はないので、Dispostedメソッドは呼び出されていません.)
  • うん。なぜ1と2のように2つの方法があるのでしょうか。


    恐らく.Observableがリソースを閉じるときに何かを実行したい場合は、
    #1のように記入し、そうでない場合は#2のように記入すればよい.

    ではDisposablesを知らなくてもいいですか?


    質問(…)そうではありませんが、上ではそう言っていますよね?通常、Observableが終了すると(完了またはエラーイベントのため)、関連するすべてのリソースが自動的に無効になります.
    ただし、完全またはエラーで終了しても、アップルの公式ドキュメントを表示します.
    自動無効化ではなく、
  • リソースを直接無効にすることをお勧めします.
  • △それがDisposedを知っている理由です.
    Disposableは
  • 取り消し
  • 使用不可
  • リソース
  • 使用

    では、どのようにしてリソースを解放し、実行をキャンセルしますか?


    コードで表示します.

    リソースを無効にします。

    let subscription1 = Observable.from([1,2,3])
        .subscribe { element in
        print("Next",element)
    } onError: { error in
        print("Error",error)
    } onCompleted: {
        print("Completed")
    } onDisposed: {
        print("Disposed")
    }
    
    subscription1.dispose()
    前述したように、dispose()メソッドを使用してリソースを無効にすることができます.
    しかし、公式文書はこのような方法で資源を解除することを提案していない.
    なぜ元に戻すことを提案しないのかを振り返ってみましょう.

    実行をキャンセルした場合

    // #1
    let subscription2 = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
        .subscribe { element in
            print("Next",element)
        } onError: { error in
            print("Error",error)
        } onCompleted: {
            print("Completed")
        } onDisposed: {
            print("Disposed")
        }
    // #2
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        subscription2.dispose()
    }
    +コードの簡単な説明:
  • #1は、増加した整数を1秒間隔で無限に放出する.
  • #2は、無限解放イベントを実行する#1を停止する必要があるため、dispose()メソッドを直接使用して停止する.
  • 実行結果

    はい、何か問題がありますか.
    結果を見てみましょう.
    イベントは0->次の1->次の2->の表示順で発生します.
    変なところがありますよね?
    Observableが最後のイベントを処理すると、最後に呼び出されたCompletedは表示されません.
    dispose()メソッドを使用してObserverableを強制閉鎖したため!
    このように強制的に閉じる場合は、Completedを呼び出すことができないなどの問題のため、リソースを他の方法で閉じることをお勧めします.

    DisposeBag


    これです.DisposeBagを使用してリソースを解除する必要があります.
    やってみましょう.
    var bag = DisposeBag()
    
    Observable.from([1,2,3])
        .subscribe{
            print($0)
        }
        .disposed(by: bag) // #1
        
    bag = DisposeBag()  // #2
  • #1のようにパラメータでdisposeBagを渡すと、subscribeが返す使い捨て製品がDisposeBagに追加されます.
  • 上記の方法のように、観察可能な使い捨て用品をdisposebagに複数格納することができ、disposebagに追加された使い捨て用品はdisposebag解除時に一緒に使用される.
    では、DisposeBagのリソースをどのように無効にしますか?
    簡単な方法は2つあります.

  • あるいは#2のように新しいDisposeBagを割り当てます.

  • 最初から#2の変数をオプション変数にしてnilを入れればいいです.
  • 結果.
    このようなObservableによって転送されるイベントが終了した場合、すべてのリソースを無効にするために、上記の方法のDisposeBagを使用することをお勧めします.
    うん.

    書いているうちに長くなってしまうので、簡単に要約すると!

  • 傍観者が購読した観測可能なイベントの終了時にリソースを解放するために、以下のコード処理(by:)方法でDisposeBagに格納し、DisposeBagのリソースを解放し、すべてのリソースを解放する!
  • こんな感じで
    Observable.from([1,2,3])
        .subscribe{
            print($0)
        }
        .disposed(by: bag) // #1