这种 MVVM 方法会产生内存泄漏吗?
Will this approach to MVVM produce memory leaks?
我发现输入和重新输入引发 属性 更改事件的相同 属性 getter 和 setter 是乏味的,而且可能容易出错,因为 属性名称作为键入的字符串传递。在寻找更简单的方法后,我创建了以下通用 class:
public class ObservableProperty<T> : INotifyPropertyChanged
{
private T _backingField;
public T Value
{
get { return this._backingField; }
set
{
if (!EqualityComparer<T>.Default.Equals(this._backingField, value))
{
this._backingField = value;
this.TriggerPropertyChangedEvent();
}
}
}
/// <summary>
/// Creates an observable property with a default initial value.
/// </summary>
public ObservableProperty() : this(default(T)) { }
/// <summary>
/// Creates an observable property with the specified initial value.
/// </summary>
/// <param name="initialValue">The value to initialize the observable property to.</param>
public ObservableProperty(T initialValue)
{
this.Value = initialValue;
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void TriggerPropertyChangedEvent([CallerMemberName]string propertyName = null)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion // INotifyPropertyChanged Implementation
}
现在无需在整个 ViewModel 上实施 INotifyPropertyChanged 并键入所有支持字段和 属性 getter 和 setter 长手,所有需要做的是:
public ObservableProperty<string> BindableText { get; private set; }
然后在构造函数中:
this.BindableText = new ObservableProperty<string>("Default Text");
视图现在将绑定到 XAML 中的 BindableText.Value。
所以每个 属性 都会有自己的 INotifyPropertyChanged 实现,自己成为一个迷你视图模型,创建这些实例的模型和视图模型根本不需要实现接口。
这很好用,可以绑定的属性很容易创建。 ViewModel 甚至可以引用模型上的可观察属性,例如:
public ObservableProperty<int> MyNumber { get { return MyModel.Number; } }
以便视图不直接绑定到模型上的属性,只能通过它们的视图模型间接绑定。
我的问题是,因为这不是我有很多经验的事情,采用这种方法是否会存在任何潜在的软内存泄漏,我可以采取某种措施来应对?
is will there be any potential soft memory leaks by taking this approach that I could take measures against somehow?
发生内存泄漏的风险与标准 INotifyPropertyChange
方法相同:
如果这些 ObservableProperties
用于 XAML
中的绑定,则不会发生内存泄漏,因为 WPF
使用 Weak Events
来绑定实现对象的属性INotifyPropertyChange
界面。
如果这些 ObservableProperties
在代码中用于订阅 INotifyPropertyChange
事件,则可能是内存泄漏。
例如,如果 ViewModel
订阅 Model
的 ObservableProperty
对象的 INotifyPropertyChange
事件,那么这个 ViewModel
将不会被垃圾回收直到 Model
被垃圾回收或 ViewModel
退订。如果为一个 Model
.
创建了许多 ViewModels
,则此泄漏可能会很明显
我发现输入和重新输入引发 属性 更改事件的相同 属性 getter 和 setter 是乏味的,而且可能容易出错,因为 属性名称作为键入的字符串传递。在寻找更简单的方法后,我创建了以下通用 class:
public class ObservableProperty<T> : INotifyPropertyChanged
{
private T _backingField;
public T Value
{
get { return this._backingField; }
set
{
if (!EqualityComparer<T>.Default.Equals(this._backingField, value))
{
this._backingField = value;
this.TriggerPropertyChangedEvent();
}
}
}
/// <summary>
/// Creates an observable property with a default initial value.
/// </summary>
public ObservableProperty() : this(default(T)) { }
/// <summary>
/// Creates an observable property with the specified initial value.
/// </summary>
/// <param name="initialValue">The value to initialize the observable property to.</param>
public ObservableProperty(T initialValue)
{
this.Value = initialValue;
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected void TriggerPropertyChangedEvent([CallerMemberName]string propertyName = null)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion // INotifyPropertyChanged Implementation
}
现在无需在整个 ViewModel 上实施 INotifyPropertyChanged 并键入所有支持字段和 属性 getter 和 setter 长手,所有需要做的是:
public ObservableProperty<string> BindableText { get; private set; }
然后在构造函数中:
this.BindableText = new ObservableProperty<string>("Default Text");
视图现在将绑定到 XAML 中的 BindableText.Value。
所以每个 属性 都会有自己的 INotifyPropertyChanged 实现,自己成为一个迷你视图模型,创建这些实例的模型和视图模型根本不需要实现接口。
这很好用,可以绑定的属性很容易创建。 ViewModel 甚至可以引用模型上的可观察属性,例如:
public ObservableProperty<int> MyNumber { get { return MyModel.Number; } }
以便视图不直接绑定到模型上的属性,只能通过它们的视图模型间接绑定。
我的问题是,因为这不是我有很多经验的事情,采用这种方法是否会存在任何潜在的软内存泄漏,我可以采取某种措施来应对?
is will there be any potential soft memory leaks by taking this approach that I could take measures against somehow?
发生内存泄漏的风险与标准 INotifyPropertyChange
方法相同:
如果这些
ObservableProperties
用于XAML
中的绑定,则不会发生内存泄漏,因为WPF
使用Weak Events
来绑定实现对象的属性INotifyPropertyChange
界面。如果这些
ObservableProperties
在代码中用于订阅INotifyPropertyChange
事件,则可能是内存泄漏。
例如,如果 ViewModel
订阅 Model
的 ObservableProperty
对象的 INotifyPropertyChange
事件,那么这个 ViewModel
将不会被垃圾回收直到 Model
被垃圾回收或 ViewModel
退订。如果为一个 Model
.
ViewModels
,则此泄漏可能会很明显