web-dev-qa-db-ja.com

`CreateObject()`を使用して変数を設定した場合、使用後に `Nothing`に設定してクリーンアップする必要がありますか?

CreateObject()を使用して変数を設定した場合、使用後にNothingに設定して変数をクリーンアップする必要がありますか?

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

私はちょうど見つけました この投稿 by Eric Lippert

スクリプトエンジンは、これらの変数がスコープ外になると自動的にクリアされるため、スコープ外になる前にステートメントをクリアしても意味がないようです。

19
Nick Strupat

CreateObject()を使用して変数を設定した場合、使用後にNothingに設定して変数をクリーンアップする必要がありますか?

通常はそうしませんが、それはあなたがするVBコミュニティで伝承になりました。あなたが迷信者であるならば、それはそうしません傷つく変数を使い終わったらNothingに設定することで邪眼になりますが、それが何かを助けることはめったにありません。

変数をNothingに設定する必要があるまれなケースは、次のような場合です。

  • ガベージコレクタがクリーンアップできない循環参照を作成しました
  • オブジェクトは高価ですが、変数の有効期間が長いため、早期にクリーンアップする必要があります
  • オブジェクトの実装には、維持する必要のある特定のシャットダウン順序が必要です
  • 等々。

これらのケースのいずれにも当てはまらない場合は、変数をNothingに設定しません。私はそれで問題があったことはありません。

31
Eric Lippert

私はめったにこれをしません:-

Set foo = Nothing 

これが理由です...

考慮してください:-

Function DoStuff()
    Dim foo : Set foo = CreateObject("lib.thing")
    ''# Code that uses foo
    Set foo = Nothing
End Function

とにかくfooがスコープ外に渡そうとしているのでNothingfooに割り当てることは不要なので、気にしません。

考慮してください:-

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に割り当てることが推奨される場合がありますが、私は特別な場合にそれを行う傾向があります。通常のコードでは、それが必要になることはめったにありません。

おそらく、「常に何も設定しない」キャンプの背後にある要因の1つは、多くのVBScripterがFunctionおよびSubプロシージャに十分に考慮されていないシーケンシャルスクリプトを作成することです。

12
AnthonyWJones

変数がモジュールまたはグローバル変数(モジュールの上部近く、プロシージャの外側で宣言されている)の場合、スクリプトの最後で変数が自動的にスコープ外になることはありません。状況によっては問題が発生する可能性があるため、変数を何も設定しないことを検討してください(または、オブジェクト変数でない場合はデフォルトです)。

0
ChrisB