The code generator statically determines the lifetimes of handle objects. It can reuse memory rather than rely on a dynamic memory management scheme such as reference counting or garbage collection. It generates code that does not use dynamic memory allocation or incur the overhead of run-time automatic memory management. These characteristics of the generated code are important for some safety-critical and real-time applications.
When you use handle objects, the static analysis that the code generator uses requires that you adhere to the following restrictions:
Consider the handle class mycls
and the function usehandle1
.
The code generator reports an error because p
,
which is outside the loop, has a property that refers to a mycls
object
created inside the loop.
classdef mycls < handle properties prop end end
function usehandle1 p = mycls; for i = 1:10 p.prop = mycls; end
If a persistent variable refers to a handle object, the code
generator allows only one instance of the object during the program's
lifetime. The object must be a singleton object.
To create a singleton handle object,
enclose statements that create the object in the if isempty()
guard
for the persistent variable.
For example, consider the class mycls
and the
function usehandle2
. The code generator reports
an error for usehandle2
because p.prop
refers
to the mycls
object that the statement inner
= mycls
creates. This statement creates a mycls
object
for each invocation of usehandle2
.
classdef mycls < handle properties prop end end
function usehandle2(x) assert(isa(x, 'double')); persistent p; inner = mycls; inner.prop = x; if isempty(p) p = mycls; p.prop = inner; end
If you move the statements inner = mycls
and inner.prop
= x
inside the if isempty()
guard, code
generation succeeds. The statement inner = mycls
executes
only once during the program's lifetime.
function usehandle2(x) assert(isa(x, 'double')); persistent p; if isempty(p) inner = mycls; inner.prop = x; p = mycls; p.prop = inner; end
Consider the function usehandle3
. The code
generator reports an error for usehandle3
because
the persistent variable p
refers to the mycls
object
that the statement myobj = mycls
creates. This
statement creates a mycls
object for each invocation
of usehandle3
.
function usehandle3(x) assert(isa(x, 'double')); myobj = mycls; myobj.prop = x; doinit(myobj); disp(myobj.prop); function doinit(obj) persistent p; if isempty(p) p = obj; end
If you make myobj
persistent and enclose
the statement myobj = mycls
inside an if
isempty()
guard, code generation succeeds. The statement myobj
= mycls
executes only once during the program's lifetime.
function usehandle3(x) assert(isa(x, 'double')); persistent myobj; if isempty(myobj) myobj = mycls; end doinit(myobj); function doinit(obj) persistent p; if isempty(p) p = obj; end