7

一部のサービスからオブジェクトを取得し、データ バインディングで使用できるようにするビュー モデルがあります。オブジェクトは を実装してINotifyPropertyChangedいます。ビュー モデルでPropertyChangedは、オブジェクトの特定のプロパティが変更されたときに内部アクションを実行するイベントをリッスンしています。

これで、サービスから新しいオブジェクトが要求され、古いオブジェクトが完全に置き換えられる可能性があります。有効期間が本質的にビュー モデル自体によって制限されており、他の誰もそれへの参照を保持していない (WPF は弱いリスナーを使用している) ことを考えると、この場合、オブジェクトからサブスクライブを解除する必要がありますか? もちろん、セッターでそうするのは簡単ですが、本当にそうする必要ありますか?

public class MyViewModel : INotifyPropertyChanged
{
    private DataType myData;
    public DataType MyData
    {
        get { return myData; }
        protected set
        {
            if (value == myData)
                return;

            if (myData != null)
                myData.PropertyChanged -= DataPropertyChanged;
            myData = value;
            myData.PropertyChanged += DataPropertyChanged;

            OnNotifyPropertyChanged("MyData");
        }
    }

    public void UpdateData ()
    {
        MyData = service.GetData();
    }

    // ...
}
4

1 に答える 1

2

特に何もする必要はありませんが、完了したら、イベントから古いオブジェクトを切り離す必要があります。理由は 2 つあります。

オブジェクトがガベージ コレクションされ、イベントが発生した場合、オブジェクトがもう生きていないことを確認するのに時間がかかります。イベント ハンドラー リストから削除されることを願っています。そうでない場合は、次回もさらに時間が費やされます。

さらに重要なことは、古いオブジェクトがガベージ コレクションされておらず、イベントが発生した場合、 2 つのイベント通知を受け取ることになります。1 つは古いオブジェクトで、もう 1 つは新しいオブジェクトです。このケースは特に古いオブジェクトで処理する必要があります (そうしないと、悪いことが起こります)。

これを処理する最も簡単な方法は、完了したらイベントから切り離すことです。

于 2013-06-21T13:34:18.500 に答える