3.錯誤的WPF繫結引起的“記憶體洩漏”
阿新 • • 發佈:2020-11-02
錯誤的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回收,檢視例項數量。