3

最近、MVVMLight 3 から 4 にアップグレードしたところ、コマンドが壊れていることに気付きました。新しい RelayCommand (バージョン 3.5 で実装) で弱い参照を使用すると、使用しているコード構成が失敗する原因になっていることが判明しました。メモリリークに関連する弱い参照についていくつかの議論があることは知っていますが、それを理解していません。

これは失敗します:

private void InitCommand()
{
    Command = new SwitchMainGridCommand<SwitchMainGridToolViewModel>(this).Command;
}

失敗とは、初期化してバインドした Command プロパティを使用しようとすると、そのバッキング メソッドがガベージ コレクションされ、Command の実行に失敗することを意味します。興味深いことに、Command オブジェクトはまだ存在し、SwitchMainGridCommand のサポート プロパティだけがなくなりました。RelayCommand の弱い参照の前は、SwitchMainGridCommand が明示的に保持されていなかったとしても、Command への参照はサポート プロパティも利用できるようにしていました。

これは成功します:

SwitchMainGridCommand<SwitchMainGridToolViewModel> _refHolder = null;

private void InitCommand()
{
    _refHolder = new SwitchMainGridCommand<SwitchMainGridToolViewModel>(this);
    Command = _refHolder.Command;
}

Command が割り当てられている ViewModel で _refHolder クラス変数を作成すると、_refHolder.Command が参照するメソッド/プロパティが収集されなくなります。

これは弱い参照の望ましい動作だと思いますが、なぜそれが望ましいのかわかりません。

4

2 に答える 2

1

弱い参照と強い参照に関する MSDN の記事は次のとおりです。 MSDN Goodness

于 2013-01-07T19:42:09.787 に答える
0

たぶん、繰り返しますが、おそらくこの理由からです。

MvvmLight ロジック、およびその他の mvvm スタイルでは、ViewModel は Locator を使用したビューへの「リンク」です。xaml ページで次のページに進むと、前のページの Vm がまだ生きていて、コマンド weak Give を使用してメモリを簡単に解放できます。

2つ目は、オブジェクトの寿命をより適切に制御するための単純なもので、ロケーターにViewmodelの参照を保持する唯一のものを許可するため、唯一のものはいつどこでリリースするかを決定できます

これがあなたのお役に立てば幸いです.vmがまだしばらくの間生きていることがそれほど重要ではなく、主にソフトウェアが非常に大きなサイズのメモリを使用していない場合. alloc と dealloc は、ソフトウェアのパフォーマンスに悪影響を及ぼします

于 2014-01-14T11:06:10.277 に答える