Eri*_*k A 4 ms-access vba access-vba
我有一个非常简单的表单,它使用一个非常简单的类来处理一些事情.那个班级有一个Class_Terminate
自己清理的子.但是,当表单关闭时,似乎没有触发.
MCVE:
表单Form1,一个名为Text0的文本框,没有进一步的控件
Private myClass1 As Class1
Private Sub Form_Load()
Set myClass1 = New Class1
myClass1.InitForm Me
End Sub
Run Code Online (Sandbox Code Playgroud)
Class Class1
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
Run Code Online (Sandbox Code Playgroud)
但是,当我关闭表单时,类终止处理程序不会触发.
我尝试在类中取消设置Form对象:
Private Sub Form_Unload(Cancel As Integer)
Set myClass1.theForm = Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)
但随之而来的是混乱:关闭表单后类终止处理程序触发,但之后立即访问硬崩溃而没有任何错误消息!
关闭表单时,Access无法正常清理表单对象.
这意味着:如果对象具有对表单的开放引用,则表单对象仍然存在.如果没有对它的引用,它只能被垃圾收集器删除.
表单的第一个版本是创建内存泄漏:表单对象Form_Form1
具有对Class1
(通过MyClass1
变量)的引用,通过变量Class1
引用表单对象theForm
.这导致了参考循环.终止处理程序没有触发,因为类永远不会终止,它无限期地保留在内存中,关闭并重新打开表单只是打开了一个新的类实例.
第二个版本导致了一个问题:在基准循环被打破,引用Form1
发布第一(因为还有是参考Class1
上Form1
),造成垃圾收集器来清理,然后引用Class1
被释放,垃圾收集器试图清理Class1
,包括文本框对象SomeTextbox
,导致访问硬崩溃,因为表单对象已被清理,文本框对象无效.
解决方案是通过删除对Class1
first的所有引用来中断引用循环.这不会导致崩溃.
Private Sub Form_Unload(Cancel As Integer)
Set myClass1 = Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)
这会导致垃圾收集器首先清理Class1实例,释放对Text0的引用,然后清除表单对象,因为没有人打开引用它.
归档时间: |
|
查看次数: |
113 次 |
最近记录: |