Contenido principal

Weak References

Since R2024b

A weak reference to a handle object works much like a regular handle, but a weak reference does not affect the lifecycle of the object. In other words, if an object is only referred to by weak references, then MATLAB® deletes the object. You can use weak references to manage object lifecycles more efficiently.

Create a Weak Reference Property

You can think of strong and weak references in terms of ownership. For example, a library owns a collection of books, but the books do not own the library. The Library class defines a strong reference property, Collection, for an array of Book objects. However, Book defines a Location property for a single Library object using the WeakHandle property attribute. (See Property Attributes for more information.)

classdef Library < handle
    properties
        Collection (1,:) Book = Book.empty
    end
end
classdef Book < handle
    properties (WeakHandle)
        Location (1,1) Library
    end
end

Using this combination of a strong reference and weak reference avoids creating cycles of references that make it more difficult to clear objects from memory. In this case, a Book object alone is not enough to keep a Library object from being deleted because the Location property of the Book object only references the Library object weakly.

Create Back Pointers Using Properties Defined with WeakHandle Attribute

Data structures like trees or lists can contain objects with back pointers to objects above them in a hierarchy. Back pointers that are strong reference handles require MATLAB to do extra work when checking to see which objects can be deleted. Replacing strong references with weak references provides more efficient management of handle objects.

For example, the class Car contains properties that reference parts of a car. The class Engine represents one part that Car can reference.

classdef Car < handle
    properties
        VIN string
        EngineInstalled (1,1) Engine
    end
end
classdef Engine < handle
    properties (WeakHandle)
        InstalledIn (1,1) Car
    end
    properties
        SerialNumber string = "00000"
        LastService datetime = "today"
    end
end

The Engine class defines a weak reference, InstalledIn, back to the car that the engine is installed in. All properties defined with the WeakHandle attribute must use class validation. In this case, InstalledIn must be of type Car.

Construct myCar and myCarEngine. Assign myCarEngine to the EngineInstalled property of myCar, and set the InstalledIn property of myCarEngine to myCar.

myCar = Car;
myCarEngine = Engine;
myCar.EngineInstalled = myCarEngine;
myCarEngine.InstalledIn = myCar;

Now, both myCar and myCarEngine reference each other, although the reference from myCarEngine to myCar is a weak reference. Clear myCar.

myCar = []

The myCarEngine.InstalledIn property is now the only reference to myCar.If the handle in the InstalledIn property of myCarEngine were a strong reference, the object pointed to by myCar would still exist because it would be strongly referenced by myCarEngine.InstalledIn. However, because myCarEngine.InstalledIn is a weak reference, it does not prevent MATLAB from deleting the myCar object. Confirm that myCar is deleted by accessing myCarEngine.InstalledIn.

myCarEngine.InstalledIn
ans = 

  handle to deleted Car

Note

Calling delete on myCar deletes the object regardless of any existing references to the object, weak or strong.

Size Validation with Weak References

When a property is defined as a weak handle with size validation but no default value, MATLAB creates an array of invalid handles. For example, use the Engine class as the type of a weak handle reference in Prop1 of TestClass. Use size validation but no default value.

classdef TestClass
    properties (WeakHandle)
        Prop1 (2,2) Engine
     end
end

The default value of each element of the initial array in Prop1 is an invalid handle.

t = TestClass;
t.Prop1(1,2)
ans = 

  handle to deleted Engine

When to Use the matlab.lang.WeakReference Class

MATLAB has two ways of creating weak references: the WeakHandle property attribute and the matlab.lang.WeakReference class. A weak reference defined by the WeakHandle property attribute is scoped to the object that defines it. The WeakHandle property attribute offers more flexibility than the WeakReference class because you can use property validation, default values, and implicit conversion.

However, the WeakReference class enables you to scope a weak reference to a workspace variable without implementing your own class. The class is limited in that it can only reference scalar objects, and it does not support default values.

Create a Cache Using the matlab.lang.WeakReference Class

You can use weak references to design a cache. Because caches are usually intended for quick access to data without necessarily preserving that data, you can use weak references to help manage lifecycles of data objects. Each object in the cache can have a weak reference, but the weak references do not prevent the code that manages the cache from deleting objects.

First, define a basic class TrialData that represents experimental data.

classdef TrialData < handle
    properties
        trialNumber string = "A001"
        trialResults double = 0
    end
end

Create the basis for a cache by defining a dictionary named workingData. The dictionary maps a string-valued key to a weak reference to the data object. You cannot add properties (weak or otherwise) to a dictionary, so instead use an empty array of the matlab.lang.WeakReference wrapper class as the initial value.

workingData = dictionary(string.empty,matlab.lang.WeakReference.empty)
workingData =

  dictionary (string ⟼ matlab.lang.WeakReference) with no entries.

Construct two instances of TrialData and add them to workingData. Use the trialNumber property of the TrialData instances as the keys for the entries in the dictionary. The dictionary values are weak references to first and second because the dictionary values were initially defined as type matlab.lang.WeakReference.

first = TrialData;
second = TrialData;
second.trialNumber = "A002";
second.trialResults = 1;
workingData(first.trialNumber) = first;
workingData(second.trialNumber) = second
workingData =

  dictionary (string ⟼ matlab.lang.WeakReference) with 2 entries:

    "A001" ⟼ 1×1 matlab.lang.WeakReference
    "A002" ⟼ 1×1 matlab.lang.WeakReference

The TrialData object referenced by each dictionary value is held by the Handle property of matlab.lang.WeakReference. Access the trialResults property of the object referenced by "A002" through the Handle property.

result2 = workingData("A002").Handle.trialResults
result2 =

     1

Because the dictionary values are weak references, they do not prevent any of the objects referenced from being cleared from memory. Clear second, and confirm that the reference in the dictionary now points to a deleted object.

clear("second")
workingData("A002").Handle
ans = 

  handle to deleted TrialData

Immediate Destruction of Weak References

MATLAB immediately deletes an object that has only weak references to it. For example, construct an instance of the Example class. Set Prop using the Example constructor instead of creating a separate instance as a strong reference.

classdef Example < handle
    properties (WeakHandle)
        Prop Example
    end
end
x = Example;
x.Prop = Example;

Because the object referenced by x.Prop has only a weak reference, MATLAB deletes it immediately after it is created.

x.Prop
ans = 

  handle to deleted Example

To avoid this behavior, define a strong reference first so that MATLAB does not immediately delete the object, as shown in the Create Back Pointers Using Properties Defined with WeakHandle Attribute example.

See Also

| |

Topics