Vba 类_Terminate不从窗体对对象触发
我有一个非常简单的表单,它使用一个非常简单的类来处理一些事情。该类有一个Vba 类_Terminate不从窗体对对象触发,vba,ms-access,Vba,Ms Access,我有一个非常简单的表单,它使用一个非常简单的类来处理一些事情。该类有一个class\u Terminatesub来清理自身。然而,当窗体关闭时,似乎没有触发 MCVE: 表单Form1,一个名为Text0的文本框,没有其他控件 Private myClass1 As Class1 Private Sub Form_Load() Set myClass1 = New Class1 myClass1.InitForm Me End Sub 一班 Public theForm As
class\u Terminate
sub来清理自身。然而,当窗体关闭时,似乎没有触发
MCVE:
表单Form1,一个名为Text0的文本框,没有其他控件
Private myClass1 As Class1
Private Sub Form_Load()
Set myClass1 = New Class1
myClass1.InitForm Me
End Sub
一班
Public theForm As Form
Private WithEvents SomeTextbox As TextBox
Public Sub InitForm(frm As Form)
Set theForm = frm
Set SomeTextbox = frm.Text0
End Sub
Private Sub Class_Terminate()
MsgBox "Class1 terminated succesfully"
End Sub
但是,当我关闭表单时,类终止处理程序不会启动
我尝试在类中取消设置窗体对象:
Private Sub Form_Unload(Cancel As Integer)
Set myClass1.theForm = Nothing
End Sub
但混乱接踵而至:类终止处理程序在关闭表单后触发,但随后立即访问硬崩溃,没有任何错误消息 关闭表单时,Access不会优雅地清理表单对象 这意味着:如果对象具有对窗体的打开引用,则窗体对象将持续存在。只有在没有引用的情况下,垃圾收集器才能删除它 表单的第一个版本正在创建内存泄漏:表单对象
form\u Form1
引用了Class1
(通过MyClass1
变量),Class1
通过form
变量引用了表单对象。这导致了一个引用循环。终止处理程序没有启动,因为类从未终止,它无限期地保留在内存中,关闭并重新打开表单只是打开了该类的一个新实例
第二个版本导致了一个问题:当引用循环被破坏时,对Form1
的引用首先被释放(因为Form1
上仍然有对Class1
的引用),导致垃圾收集器将其清除,然后,对Class1
的引用被释放,垃圾收集器试图清理Class1
,包括textbox对象SomeTextbox
,导致访问硬崩溃,因为表单对象已经清理,textbox对象无效
解决方案是首先删除对Class1
的所有引用,从而中断引用循环。这不会导致崩溃
Private Sub Form_Unload(Cancel As Integer)
Set myClass1 = Nothing
End Sub
这会导致垃圾收集器首先清理Class1实例,释放对Text0的引用,然后清理表单对象,因为没有人打开对它的引用 好奇这是否是一个解决办法too@MathieuGuindon只有在您未将
与事件一起使用时才会使用。如果我理解正确,您就不能使用弱引用来侦听事件。如果您只为表单对象实现该功能,那么会出现崩溃,因为表单首先被释放,然后是保存表单上textbox对象引用的类。如果对类Class1
使用弱引用,它会在应该释放之前被释放。