【问题标题】:What are the benefits of setting objects to "Nothing"将对象设置为“无”有什么好处
【发布时间】:2018-06-27 14:37:19
【问题描述】:

我注意到 Stack Overflow 社区的一些成员会在关闭程序中使用Set Object = Nothing。我能够找到为什么这对 Access 的实例很有用,但是在为 Excel 执行此操作时没有一个令人满意的答案,所以我的问题是 在 VBA 中将对象设置为 Nothing 有什么好处?

在下面的示例代码中,设置我的对象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 

【问题讨论】:

  • 您释放内存并避免错误。通常这是使用加载到内存中的对象(例如用户表单,字典)来执行的。范围、图表、工作簿,我还没有看到在代码执行后它们不会“浪费”的问题。因此,我不明白为什么要使用这些变量。
  • 在大多数情况下,您不需要这样做。寻找讨论herehere
  • 找不到页面@Storax。听起来共识是我可以在这里删除:)
  • VBA 有垃圾收集,所以这应该不是问题......但是......我已经看到当人们忘记退出事物实例时这会导致问题......它们有时会出现继续在后台运行,占用内存。
  • @QHarr VBA 不是垃圾收集,而是引用计数。 理论上,当范围退出时,引用计数会正确耗尽。在实践中......这取决于谁为正在清除的对象编写了库 - 如果它是 VBA 类或主机应用程序中的某些东西(如Range),请不要打扰。如果它是某个引用类型库中的第 3 方类,它不会受到伤害 - 但它可能是多余的。另外值得注意的是,如果对象是用As New {class-name} 声明的,那么将其设置为Nothing 没有任何效果。

标签: excel vba


【解决方案1】:

如果这是托管的 .NET 代码(垃圾收集),您必须 Release 您访问过的每个 COM 对象,以免宿主进程 (EXCEL.EXE)可能会继续在后台运行,消耗内存并且无法完全关闭。

但这是 VBA 代码(引用计数),而且 VBA 代码使用宿主应用程序控制的对象 - 当宿主应用程序关闭时,这些对象将消失,并且发生这种情况时VBA 执行上下文早已不复存在。

换句话说,所有这些Set ... = Nothing 指令都是完全多余的。


在某些特定情况下,当您处理第 3 方 API/类型库时,对象可能没有完全清理干净。例如,您可能正在创建一个Access.Application 实例,并在 Excel 退出后发现“幽灵”ACCESS.EXE 进程在任务管理器中保持打开状态:这表明​​您正在以某种方式、某处和@泄漏对象引用987654324@ 可以帮助防止这种情况发生。

但是,我不建议像这样系统地清空所有对象引用。只有当 这样做会导致问题。即便如此,它也将是一两个物体将所有东西拖下来,而不是全部。如果 ACCESS.EXE 正常关闭,则没有理由用此类指令混淆您的代码。

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

【讨论】:

  • 感谢您解决此问题。我一直看到它,并开始怀疑我不这样做是否犯了新手错误。 Set Nothing 的所有实例都已被删除!
  • 那么这如何与 IE 实例相适应,例如,当编码人员没有退出应用程序时,即使超出范围,也会使 PC 停止运行。这是进程对对象的区别吗?
  • @QHarr 我不在 VBA 中做 IE 的东西,但如果我这样做了,我可能会将实例包含在 With 块中,例如With New InternetExplorer 或任何类名:当 With 块拥有实例时,当达到 End With 时,对象就会死亡。
  • 好的。谢谢。
  • With 块上的注释非常好
猜你喜欢
  • 2015-02-08
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
相关资源
最近更新 更多