我试图在下面的代码中找出 tmpTabPages 的生命周期。假设表单有一个名为 MyTabControl 的空 TabControl,并且有一个名为 NameCollection 的字符串集合。
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each itm In NameCollection
Dim tmpTabPage as New TabPage(itm.toString)
'Add Controls to tmpTabPage
MyTabControl.TabPages.Add(tmpTabPage)
Next
End Sub
由于 tmpTabPage 的范围是 For/Next 块,因此它的生命周期通常是直到该块的末尾,对吗?但是,由于它被添加到范围在块之外的集合中,因此它是否具有与集合(或者在本例中为 MyTabControl)相同的生命周期?最后,如果我调用 MyTabControl.TabPages.Clear 集合中的 tmpTabPages 是否会被销毁,或者它们只会占用内存?
从 Control 派生的类(包括 TabPage)最重要的是 Dispose() 方法。它们不受自动垃圾收集的影响,Winforms 保留一个内部表,将控件的句柄映射到控件引用。这就是为什么你的主窗体不会突然被垃圾收集,即使你的程序没有保留对它的引用。
将 TabPage 添加到 TabControl 的集合中会负责自动处理。这同样适用于 TabControl,它将添加到表单的 Controls 集合中。正常的事件链是您的程序或用户关闭表单。 Form 类迭代其子控件并调用其 Dispose() 方法。 TabControl 在其 Dispose() 方法中执行相同的操作,处理选项卡页。 Windows 窗口在此过程中被销毁,从该映射表中删除句柄,现在允许垃圾收集器最终收集控件的托管包装器。
有一个令人讨厌的陷阱给许多 Winforms 程序员带来了麻烦。如果您从其父级集合中删除控件,则您有责任自行处置它。删除它确实如此not自动处理它。 Winforms 通过暂时将控件重新设置为名为“停车窗口”的隐藏窗口来保持本机窗口处于活动状态。很好的功能,它允许您将控件从一个父级移动到另一个父级,而无需销毁并重新创建该控件。
但这里的关键词是“暂时”。如果您下次重新设置控件的父级,这只是暂时的。因此它从停车窗口移至新的父窗口。如果你不真正重新调整它的父级,那么它就会永远在停车窗上保持活力。吞噬资源直到程序终止。这也称为泄漏。如果您已经创建了 10,000 个窗口,而 Windows 拒绝创建另一个窗口,则可能会使您的程序崩溃。
ControlCollection.Clear() 方法在这里尤其有害。确实如此not处理掉控制装置,它们都被移到那个停车窗口。如果这不是有意的(很少是这样),您必须自己对它们调用 Dispose()。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)