3.错误的WPF绑定引起的“内存泄漏”


错误的WPF绑定

WPF绑定实际上可能会导致内存泄漏。经验法则是始终绑定到DependencyObject或INotifyPropertyChanged对象。如果你不这样做,WPF将创建从静态变量到绑定源(即ViewModel)的强引用,从而导致内存泄漏。

这里是一个例子:

"WpfApp.MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    "{Binding SomeText}">

这个View Model将永远留在内存中:

public class MyViewModel
{
    public string _someText = "memory leak";
    public string SomeText
    {
        get { return _someText; }
        set
        {
            _someText = value;
        }
    }
}

而这个View Model不会导致内存泄漏:

public class MyViewModel : INotifyPropertyChanged
{
    public string _someText = "not a memory leak";

    public string SomeText
    {
        get { return _someText; }
        set
        {
            _someText = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof (SomeText)));
        }
    }
}

是否调用PropertyChanged实际上并不重要,重要的是该类是从INotifyPropertyChanged派生的。因为这会告诉WPF不要创建强引用。

另一个和WPF有关的内存泄漏问题会发生在绑定到集合时。如果该集合未实现INotifyCollectionChanged接口,则会发生内存泄漏。你可以通过使用实现该接口的ObservableCollection来避免此问题。

验证可以参考我前几篇的方法,在构造函数中增加入实例的数量,析构函数中减少实例的数量,GC回收,查看实例数量。

相关