例如,让我们采用程序化绑定:
Binding binding = new Binding("MyProperty");
binding.Converter = new BooleanToVisibilityConverter();
binding.Source = myWindow.myObject
myButton.SetBinding(Button.VisibilityProperty, binding);
如果myWindow死了并且收集了垃圾,会发生什么......我是否也负责释放绑定,或者它知道如何自己做这件事吗?
答案 0 :(得分:2)
对于Bindings不是这样,即使您对Source
使用Binding
,也不会有内存泄漏。
验证这个
StackPanel
,TextBox
(tb1)和两个Buttons
TextBox
(tb2)Binding
,Source
设置为tb2 WeakReference
(如果我们有泄漏则不应该是GC)StackPanel
它返回false,源TextBox
(tb2)已被垃圾收集,因此我们没有内存泄漏
修改:您还可以将第一个TextBox
的创建从Xaml移至代码隐藏,并使用两个WeakReferences
(每个TextBox
一个)验证两个textBox都正确地得到了GC,你会发现这是真的。
的Xaml
<StackPanel Name="stackPanel">
<TextBox Name="textBox"/>
<Button Name="removeButton" Content="Remove" Click="removeButton_Click"/>
<Button Name="isAliveButton" Content="Is Alive?" Click="isAliveButton_Click"/>
</StackPanel>
背后的代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TextBox toBeGCdTextBox = new TextBox();
stackPanel.Children.Add(toBeGCdTextBox);
Binding textBinding = new Binding
{
Path = new PropertyPath("Text"),
Source = toBeGCdTextBox
};
textBox.SetBinding(TextBox.TextProperty, textBinding);
_weak = new WeakReference(toBeGCdTextBox);
}
private WeakReference _weak;
private void isAliveButton_Click(object sender, RoutedEventArgs e)
{
GC.Collect();
MessageBox.Show(_weak.IsAlive.ToString());
}
private void removeButton_Click(object sender, RoutedEventArgs e)
{
Debug.Assert(_weak.Target == stackPanel.Children[3]);
stackPanel.Children.Remove(stackPanel.Children[3]);
}
}
答案 1 :(得分:1)
我认为它将不被垃圾收集,如
对象是活着的,直到垃圾收集器发现了 无法再通过路径从强根引用访问对象 强引用
你仍然有一个指针binding.**Source**
。
答案 2 :(得分:0)
根据MSDN:
在C#中,垃圾收集由comman语言运行时处理 (CLR)与Java的JVM类似。垃圾收集器定期 检查内存堆中是否有任何 未引用的 对象,以及 释放这些对象持有的资源。
因此,在您的示例中,myWindow对象无法进行垃圾回收,因为存在从绑定对象到myWindow的引用。