1. 程式人生 > 實用技巧 >3.錯誤的WPF繫結引起的“記憶體洩漏”

3.錯誤的WPF繫結引起的“記憶體洩漏”

錯誤的WPF繫結

WPF繫結實際上可能會導致記憶體洩漏。經驗法則是始終繫結到DependencyObject或INotifyPropertyChanged物件。如果你不這樣做,WPF將建立從靜態變數到繫結源(即ViewModel)的強引用,從而導致記憶體洩漏。

這裡是一個例子:

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

這個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回收,檢視例項數量。