Handle Class Destructor
Basic Knowledge
Class destructor – a method named delete
that MATLAB® calls implicitly before destroying an object of a handle class. Also, user-defined code can call delete
explicitly to destroy an object.
Nondestructor – a method named delete
that does not meet the syntax requirements of a valid destructor. Therefore, MATLAB does not call this method implicitly when destroying handle objects. A method named delete
in a value class is not a destructor. A method named delete
in a value class that sets the HandleCompatible
attribute to true
is not a destructor.
Syntax of Handle Class Destructor Method
MATLAB calls the destructor of a handle class when destroying objects of the class. MATLAB recognizes a method named delete
as the class destructor only if you define delete
as an ordinary method with the appropriate syntax.
To be a valid class destructor, the delete
method:
Must define one, scalar input argument, which is an object of the class.
Must not define output arguments
Cannot be
Sealed
,Static
, orAbstract
Cannot use
arguments
blocks for input argument validation.
In addition, the delete
method should not:
Throw errors, even if the object is invalid.
Create new handles to the object being destroyed
Call methods or access properties of subclasses
MATLAB does not call a noncompliant delete
method when destroying objects of the class. A noncompliant delete
method can prevent the destruction of the object by shadowing the handle
class delete method.
A delete
method defined by a value class that is handle compatible is not a destructor, even if the delete
method is inherited by a handle subclass. For information on handle compatible classes, see Handle Compatible Classes.
Declare delete
as an ordinary method:
methods function delete(obj) % obj is always scalar ... end end
delete Called Element-Wise on Array
MATLAB calls the delete
method separately for each element in an array. Therefore, a delete
method is passed only one scalar argument with each invocation.
Calling delete
on a deleted handle should not error and can take no action. This design enables delete
to work on object arrays containing a mix of valid and invalid objects.
Handle Object During delete
Method Execution
Calling the delete
method on an object always results in the destruction of the object. The object is destroyed when the call to delete
is made explicitly in MATLAB code or when called by MATLAB because an object is no longer reachable from any workspace. Once called, a delete
method cannot abort or prevent object destruction.
A delete
method can access properties of the object being deleted. MATLAB does not destroy these properties until after the delete
methods for the class of the object and all superclasses finish executing.
If a delete
method creates new variables that contain a handle to the object being deleted, those handles are invalid. After the delete
method finishes execution, handles to the deleted object in any variables in any workspace are invalid.
The isvalid
method returns false
for the handle object within the delete
method because object destruction begins when the method is called.
MATLAB calls delete
methods in the inverse of the construction order. That is, MATLAB invokes subclass delete
methods before superclass delete
methods.
If a superclass expects a property to be managed by subclasses, then the superclass should not access that property in its delete
method. For example, if a subclass uses an inherited abstract property to store an object handle, then the subclass should destroy this object in its delete
method, but the superclass should not access that property in its delete
method.
Support Destruction of Partially Constructed Objects
Errors that occur while constructing an object can result in a call to delete
before the object is fully created. Therefore, class delete
methods must be able to work with partially constructed objects.
For example, the PartialObject
class delete
method determines if the Data
property is empty before accessing the data this property contains. If an error occurs while assigning the constructor argument to the Name
property, MATLAB passes the partially constructed object to delete.
classdef PartialObject < handle properties % Restrict the Name property % to a cell array Name cell Data end methods function h = PartialObject(name) if nargin > 0 h.Name = name; h.Data.a = rand(10,1); end end function delete(h) % Protect against accessing properties % of partially constructed objects if ~isempty(h.Data) t = h.Data.a; disp(t) else disp('Data is empty') end end end end
An error occurs if you call the constructor with a char
vector, instead of the required cell array:
obj = PartialObject('Test')
MATLAB passes the partially constructed object to the delete
method. The constructor did not set the value of the Data
property because the error occurred when setting the Name
property.
Data is empty Error setting 'Name' property of 'PartialObject' class: ...
When to Define a Destructor Method
Use a delete
method to perform cleanup operations before MATLAB destroys the object. MATLAB calls the delete
method reliably, even if execution is interrupted with Ctrl-c or an error.
If an error occurs during the construction of a handle class, MATLAB calls the class destructor on the object along with the destructors for any objects contained in properties and any initialized base classes.
For example, suppose that a method opens a file for writing and you want to close the file in your delete
method. The delete
method can call fclose
on a file identifier that the object stores in its FileID
property:
function delete(obj) fclose(obj.FileID); end
Destructors in Class Hierarchies
If you create a hierarchy of classes, each class can define its own delete
method. When destroying an object, MATLAB calls the delete
method of each class in the hierarchy. Defining a delete
method in a handle
subclass does not override the handle
class delete
method. Subclass delete
methods augment the superclass delete
methods.
Inheriting a Sealed Delete Method
Classes cannot define a valid destructor that is Sealed
. MATLAB returns an error when you attempt to instantiate a class that defines a Sealed
delete
method.
Normally, declaring a method as Sealed
prevents subclasses from overriding that method. However, a Sealed
method named delete
that is not a valid destructor does not prevent a subclass from defining its own destructor.
For example, if a superclass defines a method named delete
that is not a valid destructor, but is Sealed
, then subclasses:
Can define valid destructors (which are always named
delete
).Cannot define methods named
delete
that are not valid destructors.
Destructors in Heterogeneous Hierarchies
Heterogeneous class hierarchies require that all methods to which heterogeneous arrays are passed must be sealed. However, the rule does not apply to class destructor methods. Because destructor methods cannot be sealed, you can define a valid destructor in a heterogeneous hierarchy that is not sealed, but does function as a destructor.
For information on heterogeneous hierarchies, see Designing Heterogeneous Class Hierarchies
Object Lifecycle
MATLAB invokes the delete
method when the lifecycle of an object ends. The lifecycle of an object ends when the object is:
No longer referenced anywhere
Only referenced by weak handles
Explicitly deleted by calling
delete
on the handle
Inside a Function
The lifecycle of an object referenced by a local variable or input argument exists from the time the variable is assigned until the time it is reassigned, cleared, or no longer referenced within that function or in any handle array.
A variable goes out of scope when you explicitly clear it or when its function ends. When a variable goes out of scope and its value belongs to a handle class that defines a delete
method, MATLAB calls that method. MATLAB defines no ordering among variables in a function. Do not assume that MATLAB destroys one value before another value when the same function contains multiple values.
Sequence During Handle Object Destruction
MATLAB invokes the delete
methods in the following sequence when destroying an object:
The
delete
method for the class of the objectThe
delete
method of each superclass class, starting with the immediate superclasses and working up the hierarchy to the most general superclasses
MATLAB invokes the delete
methods of superclasses at the same level in the hierarchy in the order specified in the class definition. For example, the following class definition specifies supclass1
before supclass2
. MATLAB calls the delete
method of supclass1
before the delete
method of supclass2
.
classdef myClass < supclass1 & supclass2
After calling each delete
method, MATLAB destroys the property values belonging exclusively to the class
whose method was called. However, if the property values contain handle objects
that are still referenced outside the scope of the class, calling
delete
on the containing object does not delete the
property handle objects themselves. They can still be accessed by other existing
references.
Superclass delete
methods cannot call methods or access properties belonging to a subclass.
Destruction of Objects with Cyclic References
Consider a set of objects that reference other objects of the set such that the references form a cyclic graph. In this case, MATLAB:
Destroys the objects if they are referenced only within the cycle
Does not destroy the objects as long as there is an external reference to any of the objects from a MATLAB variable outside the cycle
MATLAB destroys the objects in the reverse of the order of construction. for more information, see Handle Object During delete Method Execution.
Restrict Access to Object Delete Method
Destroy handle objects by explicitly calling delete
on the object:
delete(obj)
A class can prevent explicit destruction of an object by setting its delete
method Access
attribute to private
. However, a method of the class can call the private
delete
method.
If the class delete
method Access
attribute is protected
, only methods of the class and of subclasses can explicitly delete objects of that class.
However, when an object lifecycle ends, MATLAB calls the object’s delete
method when destroying the object regardless of the method’s Access
attribute.
Inherited Private Delete Methods
Class destructor behavior differs from the normal behavior of an overridden method. MATLAB executes each delete
method of each superclass upon destruction, even if that delete
method is not public
.
When you explicitly call an object’s delete
method, MATLAB checks the delete
method Access
attribute in the class defining the object, but not in the superclasses of the object. A superclass with a private
delete
method cannot prevent the destruction of subclass objects.
Declaring a private delete method makes most sense for sealed classes. In the case where classes are not sealed, subclasses can define their own delete methods with public access. MATLAB calls a private superclass delete
method as a result of an explicit call to a public subclass delete
method.
Nondestructor Delete Methods
A class can implement a method named delete
that is not a valid class destructor. MATLAB does not call this method implicitly when destroying an object. In this case, delete
behaves like an ordinary method.
For example, if the superclass implements a Sealed
method named delete
that is not a valid destructor, then MATLAB does not allow subclasses to override this method.
A delete
method defined by a value class cannot be a class destructor.
External References to MATLAB Objects
MATLAB does not manage object lifecycles that involve external languages that perform their own object lifecycle management (aka, garbage collection). MATLAB cannot detect when it is safe to destroy objects used in cyclic references because the external environment does not notify MATLAB when external reference have been destroyed.
If you cannot avoid external references to MATLAB objects, explicitly break the cyclic reference by destroying the objects in MATLAB.
The following section describes how to manage this situation when using Java® objects that reference MATLAB objects.
Java References Can Prevent Destructor Execution
Java does not support the object destructors that MATLAB objects use. Therefore, it is important to manage the lifecycle of all objects used in applications that include both Java and MATLAB objects.
Java objects that hold references to MATLAB objects can prevent deletion of the MATLAB objects. In these cases, MATLAB does not call the handle object delete
method even when there is no handle variable referring to that object. To ensure your delete
method executes, call delete
on the object explicitly before the handle variable goes out of scope.
Problems can occur when you define callbacks for Java objects that reference MATLAB objects.
For example, the CallbackWithJava
class creates a Java com.mathworks.jmi.Callback
object and assigns a class method as the callback function. The result is a Java object that has a reference to a handle object via the function-handle callback.
classdef CallbackWithJava < handle methods function obj = CallbackWithJava jo = com.mathworks.jmi.Callback; set(jo,'DelayedCallback',@obj.cbFunc); % Assign method as callback jo.postCallback end function cbFunc(obj,varargin) c = class(obj); disp(['Java object callback on class ',c]) end function delete(obj) c = class(obj); disp(['ML object destructor called for class ',c]) end end end
Suppose that you create a CallbackWithJava
object from within a function:
function testDestructor cwj = CallbackWithJava ... end
Creating an instance of the CallbackWithJava
class creates the com.mathworks.jmi.Callback
object and executes the callback function:
testDestructor
cwj = CallbackWithJava with no properties. Java object callback on class CallbackWithJava
The handle variable, cwj
, exists only in the function workspace. However, MATLAB does not call the class delete
method when the function ends. The com.mathworks.jmi.Callback
object still exists and holds a reference to the object of the CallbackWithJava
class, which prevents destruction of the MATLAB object.
clear classes
Warning: Objects of 'CallbackWithJava' class exist. Cannot clear this class or any of its superclasses.
To avoid causing inaccessible objects, call delete
explicitly before losing the handle to the MATLAB object.
function testDestructor cwj = CallbackWithJava ... delete(cwj) end
Manage Object Lifecycle in Applications
MATLAB applications that use Java or other external-language objects should manage the lifecycle of the objects involved. A typical user interface application references Java objects from MATLAB objects and creates callbacks on Java objects that reference MATLAB objects.
You can break these cyclic references in various ways:
Explicitly call
delete
on the MATLAB objects when they are no longer neededUnregister the Java object callbacks that reference MATLAB objects
Use intermediate handle objects that reference both the Java callbacks and the MATLAB objects.