考虑下面的struct
和class
:
public struct DemoStruct
{
public DemoStruct(int value)
{
Value = value;
}
public int Value {get; }
}
public class DemoClass : INotifyPropertyChanged
{
private DemoStruct _demo;
public DemoStruct Demo
{
get => _demo;
set {_demo = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Demo)); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
并且,假设DataContext
是DemoClass
的示例,考虑以下绑定:
<Label Content="{Binding Demo.Value}"/>
到目前为止,我已经了解到绑定到一个不是DependencyObject
或没有实现INotifyPropertyChanged
的对象可能会导致内存泄漏,例如Why does implementing INotifyPropertyChanged avoid memory leaks in WPF?。
我想知道的是WPF将如何处理对struct
属性的绑定。
我的DemoStruct
没有实现INotifyPropertyChanged
,因为它是一个不可变的结构。
我假设它将被WPF装箱,但是由于对装箱的struct
示例的“强引用”,这是否也会造成内存泄漏?
而且,由于每当WPF访问该属性时都会创建一个新框,所以这些都会泄漏吗?
为了安全起见,我们会跟进:
如果要将绑定更改为:
<Label Content="{Binding Demo}"/>
尽管进行了装箱,但这不应该导致泄漏,因为WPF不必将任何事件处理程序附加到“Demo”,对吗?
1条答案
按热度按时间rqenqsqc1#
简短的回答是肯定的,除非你使用mode= onetimebindings。
https://learn.microsoft.com/en-us/dotnet/api/system.windows.data.bindingmode?view=windowsdesktop-7.0
结构本身不会导致内存泄漏。
该结构体上的属性就可以了。
Demo是类中的一个属性,它实现了Inotifypropertychanged。如果你绑定到Demo,那么这不会导致泄漏,但是你会得到一个结构。这可能不是很有用。
如果你绑定到Demo.Value,那么它是一个结构体上的属性,这将导致一个硬引用被创建。除非...
既然Demo是不可变的,那么也许在你的用例中你可以尝试一次性绑定,这样就不关心任何属性的改变。
https://learn.microsoft.com/en-gb/archive/blogs/jgoldb/finding-memory-leaks-in-wpf-based-applications
如果你切换出Demo,那么你可以考虑一个转换器来读取数据输出值。绑定到Demo并使用一个转换器,然后读取值并返回它。如果你有多个属性,可能会有点笨拙。
或者,您可以用视图模型中的另一个属性 Package Demo.Value。当演示更改时, Package 器属性上的Raise属性也会更改。