【Unity】UniRxの止める

UniRxを使っていてタイマーみたいなものを実装したときに必要なくなった場合にどう止めるのかを調べたことをメモとしてブログに書いていきたいと思います。 すでに先人が丁寧にWebで公開していましたので、それをそのまま参考にしました。

UniRxを止める

今回実装が必要になったのが、Observable.Interval()を止める方法です。 任意の場所で止める際には次のような実装を行いました。 [c] int count = 0; Var disposable = new SerialDisposable ();

disposable.Disposable = Observable.Interval (System.TimeSpan.FromSeconds (1)).Subscribe (_ => { count += 1; Debug.LogError (count); }).AddTo (this); [/c]

UniRxの挙動を止めたいタイミングで、IDisposableのDisposeメソッドを使います。 [c] disposable.Dispose(); [/c]

AddTo()

AddTo()を使うことで、引数にしたGameObjectが破棄されたときにUniRxも止まります。 通常はこのAddTo()を忘れずに使用していれば問題がないかと思います。 [c] private ReactiveProperty<string> name = new ReactiveProperty<string>(); name.Subscribe(SetName).AddTo(this); [/c]

Dispose()

Observable.Intervalは戻り値として IDisposableのオブジェクトを返します。 これを使ってDisposeすればUniRxが止まります。 c#のRxでは、解除、取り消しといった操作をIDisposableを使います。 いまさら聞けないReactive Extensions.1

さきほどの記述ではローカル変数にこのIDisposableを格納できるSerialDisposableを使っています。

  • SerialDisposable
  • SingleAssignmentDisposable
  • CompositeDisposable

IsDisposed

Rxが停止したかどうかはIsDisposedを使えば確認ができます。 [c] if (!disposable.IsDisposed) { disposable.Dispose(); } [/c]

SerialDisposable

IDisposableのオブジェクトを保持できるクラス。 上書き可能、上書きをした場合に前のRxは停止する。

SingleAssignmentDisposable

SerialDisposableとほぼ同じだが、上書きすると例外が発生する。

CompositeDisposable

Listのように複数のIDisposableを格納でき、同時に複数のRxを止めることができます。 [c] Var compDisposable = new CompositeDisposable (); compDisposable.Add (disposable); compDisposable.Add (disposable2); compDisposable.Add (disposable3);

// 削除もできます compDisposable.Remove (disposable2);

compDisposable.Dispose (); [/c]

最後に

UniRxは便利な機能ですが、停止処理を上手く書かないと大変なことになりそうですので、利用用途を限定して使うのが安全です。 できれば、Dispose()を使って止める手段は取らずに、AddTo()だけで挙動を制御したいです。

【参考】 UniRxのシンプルなサンプル その9(TimerとInterval 一定時間後に実行

[UniRx]購読を停止する

UniRxはこちらから入手できます。