By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,089 Members | 2,069 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,089 IT Pros & Developers. It's quick & easy.

Destroying A Collection Contained in Another Collection

P: 43
This link mentions a concept that is new to me - Destroying objects by letting a collection hold the reference to it, destroying the original instance and then when done, removing that member of the collection to destroy the object

I'm wondering if the same thing is true for collections of collections.

I created a public collection to hold values for forms to set and for queries to use. (I am putting a function that fetches the value in a query calculated field).

Anyway. The collection I created holds sub-collections containing values. Here is a simplified example.

Expand|Select|Wrap|Line Numbers
  1. Public colVals as New Collection
  2. ---------------------------------------
  3. sub test()
  4. Dim col as New Collection
  6. ' Add a value to a local collection
  7. col.Add "hi","hi"
  9. ' Add this collection to a global collection
  10. colVals.Add col, "col"
  12. Set col = Nothing
  13. ' The global collection now owns the reference to the collection
  15. End Sub
  17. ------------------------------------
  18. Sub test_2()
  19. ' When you run this you can see the sub collection is still persistent
  21. MsgBox colGlobalVal.Item("col")("hi")
  23. End Sub
  24. ------------------------------------
  26. Sub Remove_it()
  27. ' Presumably this destroys the sub collection just as
  28. ' Set col = Nothing
  29. ' would normally destroy it
  31. colGlobalVal.Remove ("col")
  33. End Sub
Is it safe to assume that removing the member, as in - "Remove_it" - actually sets the sub-collection ("col" in this example) to Nothing?

I can find no other way to set it to Nothing.
Apr 6 '12 #1
Share this Question
Share on Google+
4 Replies

P: 62
I don't see anything in that link that talks about destroying objects. However, take a look at this link, under "Garbage Collection and the Finalize Destructor". It seems that (at least in VB6), the technique used is "Reference Counting", which means that once there are no object variables referencing an object instance, the object instance is destroyed, so in your case, the object should be destroyed once it's removed from the collection.

1. When you create an object instance (assigned to an object variable), the reference count for that instance is one.

2. When you add the object reference of that instance to the collection, the reference count increases to two.

3. Then, when you Set the object variable to Nothing, the reference count decreases to one (so the object instance will NOT be destroyed yet).

4. When you finally remove the object reference from the collection, the reference count decreases to zero, and that is when the object instance is destroyed. Or in the newer garbage-collection systems, the object will now be "orphaned" and will be destroyed "soon".
Apr 7 '12 #2

P: 43
Interesting. I wonder if MS Access works the same way.

Here is the section from that site that I was referring to:
In order to use collections to manage class objects, you must do the following:
  • Create an instance of the class
  • Set the properties and methods of the class
  • Add the class to a public collection
  • Unload the instance of the class
You might expect that unloading the instance of the class results in the class being closed and terminated. However, the class object persists because you add it to a collection, which then owns the reference to the class. This is a very powerful technique that allows you to control object references through a collection; the class object does not terminate until you remove it from the collection.

The following example creates a class object and a form object, and then manages both objects from a collection in a standard module.

I guess they refer to it as "terminate" rather than "destroy", now that I look at it again.

I wonder if "terminate" can be interpreted as set to Nothing.
Apr 7 '12 #3

Expert Mod 15k+
P: 31,494
I wonder if "terminate" can be interpreted as set to Nothing.
No. I don't believe so, as the concepts are appropriate to different types of objects. This is clouded in VBA as it has Object variables, that other languages may refer to as simply pointers. Setting an object variable to Nothing is simply clearing a pointer. When all pointers are thus cleared the object itself (rather than any pointer) may be cleared away. Do you see the fundamental difference here between an object (an area of memory that maintains various attributes of a conceptual object) and what VBA refers to as an object, which is simply a long-pointer to that same area of memory. It's done to make life easier for those that don't understand the workings, but it makes understanding those workings somewhat more complicated. In VBA an Object variable is not an Object.
Apr 8 '12 #4

P: 62
Yes, NeoPa's correct. There's a distinction between an object instance and a variable which refers to it. When you declare the variable of a certain object type, you're not declaring that it IS the object, but rather, that it refers to an object of that type. That is why you can use a variant or an object of the generic Object type to hold just about any object (of any type).

Note that when you declare an variable with an object type without using the New keyword, it starts of as just Nothing, and does not refer to any object yet. The New keyword just indicates that the new variable starts of as a entirely New object, e.g.
Expand|Select|Wrap|Line Numbers
  1. Dim r as New Command
In that case, there's both a "new" variable and a new object
It is probably faster but equivalent to:
Expand|Select|Wrap|Line Numbers
  1. Dim r As Command ' Declares r to be able to refer to an object (only) of type Command
  2. Set r=New Command ' Creates a new Command object and places the reference to that new object in r
Setting an variable that refers to an object instance to Nothing will just decrease the reference count, and does not cause VB to free up the memory for that variable unless the reference count becomes zero, so continuing my earlier example,
Expand|Select|Wrap|Line Numbers
  1. Dim r As Command ' Declares r to be able to refer to an object (only) of type Command
  2. Dim r2 As Command
  3. Set r = New Command ' Creates a new Command object and places the reference to that new object in r
  4. r.Name = "NewCommandObject"
  5. Set r2 = r ' There's still only ONE object (the new Command created two lines above), but both r and r2 refers to it
  6. MsgBox r2.Name
  7. Set r = Nothing ' The Command object STILL exists, but now only r2 refers to it
  8. 'MsgBox r.Name ' Causes an error, because r does not REFER to any valid object
  9. MsgBox r2.Name
  10. Set r2 = Nothing ' Cause Access to be able to free up memory for the object instance that r2 refers to
Edit: Included an example and changed the object type to Command so that code can actually be tested in Access. You might need to add the reference to the ActiveX Data Objects library.
Apr 9 '12 #5

Post your reply

Sign in to post your reply or Sign up for a free account.