Excel VBA: уничтожение коллекции объектов уничтожает каждый объект?

скажем, у меня есть коллекция MyCollection объектов MyClass.

тут Set MyCollection = Nothing вызовите деструктор каждого содержащегося объекта или я должен позаботиться о настройке каждого объекта = Nothing индивидуально?

Я, очевидно, забочусь о причинах утечки памяти.

Dim MyCollection As Collection
Set MyCollection = New Collection
... 'add objects of type MyClass here
Set MyCollection = Nothing 

вызывает ли уничтожение этого класса деструктор каждого отдельного объекта?

2 ответов


все объекты MyClass будут уничтожены при уничтожении MyCollection, если они не ссылаются где-то еще.

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

последняя переменная MyClass в середине вашего sub будет ссылаться на один экземпляр MyClass, если вы явно не установите для него значение Nothing. Одна переменная класса вряд ли вызовет заметную проблему с памятью.

Sub MakeClassColl()

    Dim MyCollection As Collection
    Dim i As Long
    Dim clsMyClass As MyClass

    Set MyCollection = New Collection

    For i = 1 To 3
        Set clsMyClass = New MyClass
        MyCollection.Add clsMyClass
        'Check1
    Next i

    Set MyCollection = Nothing
    'Check2

End Sub

проверка 1:

  • i=1: MyClass1 (экземпляр 1) имеет счетчик ссылок 2. Одной переменной, для коллекция
  • i=2: MyClass1 имеет rc 1 (потерянный clsMyClass, все еще имеет коллекцию), MyClass2 имеет rc 2
  • i=3: MyClass1 еще 1, MyClass2 падает до 1, MyClass3 имеет rc 2

проверка 2:

  • каждый экземпляр MyClassi в коллекции падает на один. MyClass1 и 2 идут к нулю. MyClass3 падает до 1, потому что clsMyClass все еще ссылается на него (я не уничтожил clsMyClass после добавления его в коллекция.)

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

Dim MyCollection As Collection
Set MyCollection = New Collection

Call MyCollection.Add(New MyClass)
Call MyCollection.Add(New MyClass)
Call MyCollection.Add(New MyClass)

Set MyCollection = Nothing

длинный ответ: это зависит. Ответ "да", если единственной ссылкой на содержащиеся объекты является ссылка, содержащаяся в коллекции, что имеет место в вашем простом примере. На VBA знайте, что все ваши экземпляры MyClass больше нигде не ссылаются и уничтожают их. (Это приведет к вызову каждого экземпляра объекта Class_Terminate метод.)

но вы должны быть осторожны, если у вас есть другие ссылки на эти объекты. В этом утверждении нет ничего волшебного Set MyCollection = Nothing. Это тот факт, что это заставляет VBA уничтожать коллекцию, что в свою очередь заставляет ее уничтожать объект внутри. (И, конечно же, коллекция уничтожается только этой строкой если MyCollection contaqins единственная ссылка на него.)

хороший источник, чтобы узнать больше о том, как VBA object lifetimes-это старое руководство программиста Visual Basic 6.0, в частности раздел "ссылки на объекты и подсчет ссылок":

http://msdn.microsoft.com/en-us/library/aa263495 (v=VS.60).aspx