How to destroy an object

偶尔善良 提交于 2020-06-11 16:48:47

问题


It seems that Set Object = Nothing didn't destroy the Fs Object in this code:

Sub Test2()
    Dim Fs As New FileSystemObject
    Set Fs = Nothing
    MsgBox Fs.Drives.Count ' this line works
End Sub

The last line works with no errors!. thats mean Fs Object is still exists, right?.

So how to destroy this Fs Object.


回答1:


Another way to ensure proper destruction of an object, is to yield its object reference to a With block (i.e. don't declare a local variable):

Sub Test()
    With New FileSystemObject
        MsgBox .Drives.Count
    End With
End Sub

The object only ever exists inside the With block, and when execution reaches the End With token, if you try it with a custom class module you'll notice that the the class' Class_Terminate handler runs, effectively confirming the proper destruction of the object.

As for the As New quirk, as was already explained, if you intend to set the object reference to Nothing inside that scope, don't declare it with As New, because VBA will set the object reference to Nothing, but will also happily ("helpfully") create a new instance for you as soon as you re-reference it again, be it only to verify that the object Is Nothing.

Side note, this (annoying) counter-intuitive behavior is specifically what's behind the reasoning for Rubberduck's Object variable is self-assigned code inspection:

(note: if you've got code you want to inspect, know that it runs much faster in the actual VBE than on the website)

(if it wasn't clear already: I'm heavily involved with the Rubberduck project)




回答2:


it must have to do with the "declare & instantiate" pattern, most often addressed as a "to be avoided" pattern

if you split them, you get Nothing after setting it to:

Sub Test2()
    Dim Fs As FileSystemObject
    Set Fs = New FileSystemObject
    Set Fs = Nothing
    MsgBox Fs.Drives.Count ' this line DOESN'T work
End Sub



回答3:


This amended code seems to work fine. Seems a nuance with the dim/new on the same line. Hopefully someone else can give a better idea as to the reasoning.

As others have commented, if it is a dim within the sub then it will be collected after the sub completes anyway.

Sub Test2()
    Dim Fs As FileSystemObject
    Set Fs = New FileSystemObject
    Set Fs = Nothing
End Sub


来源:https://stackoverflow.com/questions/42164719/how-to-destroy-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!