将对象设置为“Nothing”的好处是什么?

12
我注意到Stack Overflow社区的一些成员在关闭过程中会使用Set Object = Nothing。我能找到这在Access实例中很有用的原因,但是当涉及到Excel时,没有一个令人满意的答案,所以我的问题是将对象设置为Nothing在VBA中有哪些好处? 在下面的示例代码中,将我的对象wsTest设置为Nothing是浪费空间吗?如果这样做确实是好习惯,为什么?
Dim ws as Worksheet
Dim Test as Range

Set ws = Sheets(“Sheet1”)
Set Test = ws.Range(“A1”)

    'Utilize Test variable (copy, paste, etc)

Set Test = Nothing
Set ws = Nothing

Exit Sub 

1
你可以释放内存并避免错误。通常,这是通过加载到内存中的对象(例如用户窗体、字典)来执行的。范围、图表、工作簿,我还没有看到它们在代码执行后不会进入“废物”状态的问题。因此,我不明白为什么要对这些类型的变量进行释放。 - Sgdva
1
在大多数情况下,您不需要这样做。请查看此处的讨论:https://blogs.msdn.microsoft.com/ericlippert/2004/04/28/when-are-you-required-to-set-objects-to-nothing/ 或 https://dev59.com/WXRB5IYBdhLWcg3wxZ_Y - Storax
页面未找到 @Storax。听起来大家的共识是我可以直接删除这里 :) - urdearboy
VBA有垃圾回收机制,所以这不应该是一个问题...然而...当人们忘记退出实例时,我曾经看到过这会导致问题...它们有时会在后台继续运行并占用内存。 - QHarr
5
@QHarr VBA不是自动垃圾回收,而是引用计数。 理论上,在范围退出时,引用计数会适当减少。 在实践中......这取决于编写清除对象的库的人 - 如果是VBA类或主机应用程序中的某些内容(如“Range”),则不必担心。 如果是来自某个参考类型库的第三方类,则可能无妨 - 但可能是多余的。 还值得注意的是,如果对象是使用“As New {class-name}”声明的,则将其设置为“Nothing”根本没有任何效果。 - Mathieu Guindon
@MathieuGuindon 哦不......谢谢您的纠正。这是一个非常有用的评论。我希望下面的答案中已经包含了所有内容,因为我将会收藏它。 - QHarr
1个回答

17
如果这是托管的.NET代码(它是“垃圾回收”的),你必须释放每个你曾经访问过的COM对象,否则主机进程(EXCEL.EXE)可能会保持在后台运行,消耗内存并无法完全关闭。
但这是VBA代码(它是“引用计数”),而且是使用主机应用程序控制的对象的VBA代码 - 当主机应用程序关闭时,这些对象将会消失,此时VBA执行上下文已经不存在。
换句话说,所有这些Set ... = Nothing指令是完全冗余的。
在某些特定情况下,当您处理第三方API /类型库时,对象可能无法完全清除。例如,您可能正在创建一个Access.Application实例,并发现在Excel退出后Task Manager中仍然存在一个“幽灵”ACCESS.EXE进程:这表明您在某个地方泄漏了对象引用,Set ... = Nothing可以帮助防止这种情况发生。
但是,我不建议像那样系统地将所有对象引用都设置为空。只有在不这样做会引起问题时才需要这样做。即使出现问题,也只会是一两个对象拖垮整个系统,而不是全部对象。如果ACCESS.EXE正确关闭,则没有理由在代码中添加这样的指令。

避免将对象引用存储在全局状态中也很有帮助。如果一切都是本地的,在理论上,所有涉及的对象都会在本地作用域退出时立即销毁。


那么,这与IE实例如何配合呢?例如,即使编码人员没有退出应用程序,它仍会使PC停滞不前。这是过程优于对象的区别吗? - QHarr
7
@QHarr,我在VBA中不处理IE相关的事情,但如果我需要处理,我可能会使用 With 块来包含实例,例如 With New InternetExplorer 或者其他类名:当 With 块拥有该实例时,当到达 End With 语句时,该对象会被销毁。 - Mathieu Guindon
2
那是关于 With 块的非常好的注释。 - Kubie
@MathieuGuindon - 你应该看一下这个问题 - urdearboy
1
@urdearboy 很有趣!我已经评论了 =) - Mathieu Guindon
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接