绑定到结构的属性是否会导致WPF中的内存泄漏?

ehxuflar  于 2023-01-27  发布在  其他
关注(0)|答案(1)|浏览(148)

考虑下面的structclass

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;
}

并且,假设DataContextDemoClass的示例,考虑以下绑定:

<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”,对吗?

rqenqsqc

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属性也会更改。

相关问题