Destroying A Collection Contained in Another Collection

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Sedrick
    New Member
    • Aug 2011
    • 43

    Destroying A Collection Contained in Another Collection

    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.

    Code:
    Public colVals as New Collection
    ---------------------------------------
    sub test()
    Dim col as New Collection
    
    ' Add a value to a local collection
    col.Add "hi","hi"
    
    ' Add this collection to a global collection
    colVals.Add col, "col"
    
    Set col = Nothing
    ' The global collection now owns the reference to the collection
    
    End Sub
    
    ------------------------------------
    Sub test_2()
    ' When you run this you can see the sub collection is still persistent
    
    MsgBox colGlobalVal.Item("col")("hi")
    
    End Sub
    ------------------------------------
    
    Sub Remove_it()
    ' Presumably this destroys the sub collection just as
    ' Set col = Nothing
    ' would normally destroy it
    
    colGlobalVal.Remove ("col")
    
    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.
  • limweizhong
    New Member
    • Dec 2006
    • 62

    #2
    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".

    Comment

    • Sedrick
      New Member
      • Aug 2011
      • 43

      #3
      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.

      Comment

      • NeoPa
        Recognized Expert Moderator MVP
        • Oct 2006
        • 32633

        #4
        Originally posted by Sedrick
        Sedrick:
        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.

        Comment

        • limweizhong
          New Member
          • Dec 2006
          • 62

          #5
          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.
          Code:
          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:
          Code:
          Dim r As Command ' Declares r to be able to refer to an object (only) of type Command
          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,
          Code:
          Dim r As Command ' Declares r to be able to refer to an object (only) of type Command
          Dim r2 As Command
          Set r = New Command ' Creates a new Command object and places the reference to that new object in r
          r.Name = "NewCommandObject"
          Set r2 = r ' There's still only ONE object (the new Command created two lines above), but both r and r2 refers to it
          MsgBox r2.Name
          Set r = Nothing ' The Command object STILL exists, but now only r2 refers to it
          'MsgBox r.Name ' Causes an error, because r does not REFER to any valid object
          MsgBox r2.Name
          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.

          Comment

          Working...