如果我使用`CreateObject()`设置一个变量,使用后是否需要将其设置为`Nothing`来清除?

22

如果我使用CreateObject()设置一个变量,使用后是否需要将其设置为Nothing来清理?

Dim foo
Set foo = CreateObject("SomeAssembly")
foo Bar
Set foo = Nothing

我刚刚发现Eric Lippert发布的这篇帖子

脚本引擎会在变量超出作用域时自动清除这些变量,因此在它们超出作用域之前清除它们似乎是毫无意义的。

3个回答

34
如果我使用CreateObject()设置一个变量,我需要在使用后将其设置为Nothing来清除它吗?
通常情况下不需要,但在VB(Visual Basic)社区中流传着这种做法。如果您是个迷信者,在使用完变量后将其设置为Nothing可能有助于避免邪眼,但实际上它很少起到帮助的作用。
唯一需要将变量设置为Nothing的罕见情况包括:
- 创建了一个循环引用而垃圾回收器无法清理的情况; - 对象很昂贵,但变量的生存期很长,因此希望尽早清理它; - 对象的实现要求必须保持特定的关闭顺序等等。
如果不是这些情况之一,我就不会将变量设置为Nothing。我从来没有因此遇到过问题。

如果我没有记错,大多数循环引用都很容易清理。问题是当您在COM对象中具有循环引用(这些对象不会被垃圾回收)时发生的。 - configurator
退出程序怎么样?您必须调用application.quit()还是xlApp.quit()?如果不调用quit(),我的任务管理器中似乎会有一个额外的excel.exe进程。 - john k

16

我很少这样做:

Set foo = Nothing 

这里是为什么...
考虑以下内容:
Function DoStuff()
    Dim foo : Set foo = CreateObject("lib.thing")
    ''# Code that uses foo
    Set foo = Nothing
End Function

因为foo即将超出作用域,所以将Nothing分配给foo是多余的,所以我不会这样做。

考虑:

Function DoStuff()
    Dim foo : Set foo = CreateObject("lib.thing")
    ''# Code that uses foo
    Set foo = Nothing
    ''# Loads more code that doesn't use foo
End Function

现在这种情况下,分配Nothing是有意义的,因为否则它可能会被保留更长的时间。 然而在这种情况下,该代码可以进行重构。函数继续执行许多不需要foo的其他操作,表明foo使用的代码块实际上应该属于自己的函数:-
Function DoStuff()
    ''# Code that calls FooUsage
    ''# Loads more code that doesn't use foo
End Function

Function FooUsage(someParams)
    Dim foo : Set foo = CreateObject("lib.thing")
    ''# Code that uses foo
    FooUsage = someResult
End Function

有时为了释放内存而将变量赋值为 Nothing 是可取的,但我倾向于只在特殊情况下这样做。在正常的代码中,我发现这很少是必要的。
也许“总是设置为 nothing”阵营背后的一个驱动因素是许多VBScript编写的顺序脚本没有很好地分解为FunctionSub过程。

许多VBScript程序员编写的脚本是按顺序编写的,没有很好地分解为函数和子过程。- 确实如此!现在我知道为什么在大型旧VBScript项目中工作总是很困难。 - Bohdan Kuts

1
如果你的变量是一个模块或全局变量(在模块顶部附近声明,在任何过程之外),那么变量可能不会在脚本结束时自动超出范围。这可能会在某些情况下导致问题,因此你可以考虑将变量设置为 nothing(如果它不是对象变量,则设置为其默认值)。

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