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