WeakなReactivePropertyを作ってみた
本題
ReactivePropertyを使う際にViewModelでModel層からToReactivePropertyなどを使う場合にモデル層にSubjectすることで強参照な結びつきが生まれてViewModelがいつまでも破棄されなくなってリークしてしまいます。
その解決アプローチとしてWeakReferenceを利用できないか考えてみました。
今回のリポジトリです
WeakReactiveProperty
とりあえずWeakなReactivePropertyを作成。
まずはWeakSubscriber。
要するにWeakに購読します、みたいな感じです。
これを利用してWeakReactivePropertyを作成。
基本的に素のReactivePropertyのObservableにSubScribeしている部分をWeakSubscribeに置き換える感じです。
詳細までは確認してません。
確認
まずは効果を検証するためにみんな大好きコンソールアプリでチェック
結論としてはWeakReactivePropertyをViewModel側で使うとダメな感じ。
まだVMのインスタンスが参照されているのにGC.Collect()で回収されてしまって動かなくなってしまいます。
良いパターンとしてはModel(コードで言うとWeakServiceクラス)のパターン。
モデル層でWeakReactivePropertyを使うとうまくいっています。
これならうまくいきそうなので実際にXamarin.Formsで検証してみました。
こんな感じのVMを作ります。
App.csはこんな感じ。
NavagationPageに沢山スタックさせてからバックボタンで最初のページまで戻ってカウントアップボタンを押します。
Weakでない普通のサービスクラスを使用するとデバッグウィンドウに作ったページ分のデバッグ出力が出てしまいます。
所謂リークしている状態。
次にServiceをWeakServiceに書き換えて同じ動作を行います。
いい感じに見える(; ・`д・´)
ただNavigationスタック上にはPageは一つしかないはずなのにデバッグメッセージは2行必ずでてきちゃう。
おそらくどこかでXFが参照を持っていると思われるのだけれども深追いはしないです。
最後に
一応こんな感じでWeakReferenceを使用したReactivePropertyでModel層を作る事でリークを解決できるかもしれないです。
ReactivePropertyの有識者の方、Xamarin.Formsチョットデキル以上な方で、この記事を読んでくれた人がいましたら
問題点とかおかしい点とか指摘してもらえると助かります。
よろしくお願いします。
ではでは(‘ω’)ノ