Если я устанавливаю переменную с помощью `CreateObject()`, нужно ли мне очищать ее, устанавливая для нее значение `Nothing` после использования?

Если я устанавливаю переменную с помощью CreateObject(), нужно ли мне очищать ее, устанавливая для нее значение Nothing после использования?

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

Я только что нашел это сообщение автора Эрик Липперт:

Скриптовый движок автоматически очищает эти переменные, когда они выходят за пределы области видимости, поэтому очищать их оператор до того, как они выходят из области видимости, кажется бессмысленным.


person Nick Strupat    schedule 15.11.2011    source источник


Ответы (3)


Если я устанавливаю переменную с помощью CreateObject(), нужно ли мне очищать ее, устанавливая для нее значение Nothing после использования?

Обычно вы этого не делаете, но в сообществе VB стало известно, что вы делаете. Если вы суеверный человек, вредно защититься от сглаза, установив для переменных значение Nothing, когда вы закончите с ними работать, но это тоже редко помогает.

Редкие случаи, когда вам действительно нужно установить переменную в Nothing, это те случаи, когда:

  • вы создали циклическую ссылку, которую сборщик мусора не может очистить
  • объект дорогой, но переменная долгоживущая, поэтому вы хотите, чтобы она была очищена раньше
  • реализация объекта требует определенного порядка отключения, который необходимо поддерживать
  • и так далее.

Если я не в одном из этих случаев, я не устанавливаю переменные в Nothing. У меня никогда не было проблем с этим.

person Eric Lippert    schedule 16.11.2011
comment
Если я не ошибаюсь, большинство циклических ссылок легко очистить. Проблема возникает, когда у вас есть циклическая ссылка с COM-объектами (которые не GCed). - person configurator; 17.11.2011

Я редко делаю это: -

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 для освобождения памяти, но я склонен делать это в особых случаях. В обычном коде я нахожу это редко необходимым.

Возможно, одним из факторов, стоящих за лагерем «Всегда ничего не устанавливать», является то, что многие разработчики VBScript пишут последовательные сценарии, которые не учитываются в процедурах Function и Sub.

person AnthonyWJones    schedule 16.11.2011
comment
... многие разработчики VBScript пишут последовательные сценарии, которые плохо учитываются в функциях и подпроцедурах. — Вот оно! Теперь я знаю, почему всегда трудно работать над большими старыми проектами VBScript. - person Bohdan Kuts; 10.07.2018

Если ваша переменная является модулем или глобальной переменной (объявленной в верхней части вашего модуля, вне какой-либо процедуры), то эта переменная не может автоматически выйти из области видимости в конце вашего скрипта. Это может вызвать проблему в некоторых ситуациях, поэтому вы можете рассмотреть возможность установки переменной без значения (или по умолчанию, если это не объектная переменная).

person ChrisB    schedule 13.03.2019