Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 类_Terminate不从窗体对对象触发_Vba_Ms Access - Fatal编程技术网

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
使用弱引用,它会在应该释放之前被释放。