WeakRefs - How to Use them?

OK, so I’ve had some memory leak issues I’m trying to resolve in a web project. I’m also doing a number of things in my desktop projects where I pass a reference to a window or other control into a container control or some other location so that I don’t have to explicitly refer to a specific window or control name in code.

I’ve seen comments about WeakRefs and have looked at the docs. I understand the concept but I don’t quite understand how to practically use them in day to day coding. The example in the docs isn’t clear about that.

So how do you really use them?

Thanks.

WeakRefs are simply references to objects that can be broken when an object otherwise dies. What I typically do is use a computed property that’s backed by a WeakRef so it acts like a regular reference, but will return nil if the object has gone away.

So instead of this:

ParentWindow as Window

You do something like this:

mParentWindow as WeakRef

Then you make a computed property:

[code]ParentWindow as Window
Function Get() as Window
if mParentWindow<>nil and mParentWindow.Value<>nil then
Return Window(mParentWindow.Value)
else
Return Nil
End If
End Function

Sub Set(value as Window)
mParentWindow = new WeakRef(value)
End Sub
[/code]

You need to do some extra work in your code that references ParentWindow to check for Nil because now it’s possible that the window will not be there when you ask for it.

OK. Thanks. That makes sense. I wasn’t sure if you could somehow pass the parameter as a WeakRef, i.e.:

SomeMethod(WeakRef(Self))

Or something like that. Similar to when you use ByRef in the parameter list.

Now, do you always want to then reference the ParentWindow via the ComputedProperty using the WeakRef?

A post from some years ago that might help.

http://www.monkeybreadsoftware.eu/listarchive-realbasic-nug/2009-12-12-2.shtml

Thanks, Kem. I’ll take a look at that.

So a further question…Greg - in your example you have the following code:

Function Get() as Window if mParentWindow<>nil and mParentWindow.Value<>nil then Return Window(mParentWindow.Value) else Return Nil End If End Function

So once you return the value here, are you not returning the original Window? If I do something like this using your computed property

Dim MyWindow as Window = ParentWindow

Isn’t this the same as saying

Dim MyWindow as Window = Self

That’s where I am getting confused. Because you are returning the original window in the computed property, no?

[quote=139877:@Jon Ogden]So once you return the value here, are you not returning the original Window? If I do something like this using your computed property

Dim MyWindow as Window = ParentWindow
Isn’t this the same as saying

Dim MyWindow as Window = Self
That’s where I am getting confused. Because you are returning the original window in the computed property, no?[/quote]
ParentWindow = Self only if the control you are talking about is an instance on a Window. If you were talking about two different classes though, ones that don’t have the control/window relationship, the only safe way to link in both directions is to have a reference in one direction and a weak reference in the other. Otherwise they hold on to one another, the reference counts will never return to zero and they will never get cleaned up by the system, even if no other component in your program refers to them…

If you watch Dr. Who, you can think of a circular reference as what happens when two Weeping Angels look directly at one another. They get locked together and neither one can move because the other is watching :slight_smile: (man I hope someone gets that reference)

Don’t Blink

Back in the hip era, I knew a mad scientist who wanted to verify that mushrooms did not grow when observed by human eyes, but could grown when seen by goats…

Seemed mushrooms did not reenter with goats :wink:

I am sure Dr. Who has been written by hippies.