Setting object to Nil and destructor not getting called

I have two classes and a reference from one class to the other. The simplified code looks like this:

Class1:

Delegate Sub ActionDelegate(obj As Class1) Property SomeDelegate As ActionDelegate

Class2:

Sub SomeMethod(obj As Class1) MsgBox("I - obj2 - still exist") End

App:

Sub Open() Dim obj1 As New Class1() Dim obj2 As New Class2() obj1.SomeDelegate = AddressOf obj2.SomeMethod obj2 = Nil obj1.SomeDelegate.Invoke(obj1) End

  • On the last line, where the delegate is invoked, obj2 is shown as Nil in the debugger, though the object still exist (“I - obj2 - still exist” will pop up in a MsgBox). Why is obj2 shown as Nil if it still exists?
  • If I implement the destructor on Class2, it is not getting called on obj2 = Nil. Why is this?
  • Shouldn’t there be some kind of exception when setting an object to Nil, but due to a reference the runtime can’t really do it?
  • Is this specific to the use of AddressOf?

obj2 is just a reference variable, not an instance. There is no master variable that setting it to nil will kill the instance, the only way is to remove all references to it. In other words, as long as something references the instance it’ll stay around.

In your case both obj2 and SomeDelegate are holding reference to the same instance. Nil both and your destructor will fire.

Again, you can set all the references you want to nil, but its not until there’s 0 references that the runtime cleans it up.

The danger here is creating cyclic links. If A and B reference each other and then your app tosses any other references to A and B then you have no way to reach A or B from your code but they stay alive in memory because of the cycle. (Well, maybe you could find them by going through Runtime.ObjectIterator.)

Is there a specific design you’re trying to make or is this more for learning?

WeakAddressOf is the solution.