Генератор кода статически определяет срок службы объекта-дескриптора. При использовании объектов-дескрипторов этот статический анализ имеет определенные ограничения.
При статическом анализе созданный код может повторно использовать память, а не полагаться на динамическую схему управления памятью, такую как подсчет ссылок или сбор мусора. Генератор кода может избежать динамического выделения памяти и автоматического управления памятью во время выполнения. Эти сгенерированные характеристики кода важны для некоторых критически важных для безопасности приложений и приложений реального времени.
Ограничения см. в разделе:
Генератор кода анализирует, определены ли все переменные перед использованием. Неопределенные переменные или типы данных вызывают ошибку при создании кода. В некоторых случаях генератор кода не может определить, определены ли ссылки на объекты-дескрипторы. См. раздел Ссылки на объекты-дескрипторы могут отображаться неопределенными.
Рассмотрим класс дескрипторов mycls и функции usehandle1.
classdef mycls < handle properties prop end methods function obj = mycls(x) obj.prop = x; end end end
function y = usehandle1 p = mycls(0); % Instance of mycls with prop value 10 created for i = 1:10 p = mycls(i); % Handle object allocated inside loop end y = p.prop; % Handle object referenced outside loop end
При попытке создания кода для usehandle1 функция, генератор кода выдает ошибку. Ошибка возникает по следующей причине:
Объект-дескриптор назначается внутри for цикл. Переменная p.prop ссылается на этот объект-дескриптор.
Вне цикла переменная x относится к свойству prop объект-дескриптор.
Если постоянная переменная ссылается на объект-дескриптор, генератор кода допускает только один экземпляр объекта в течение срока действия программы. Объект должен быть одиночным. Чтобы создать одиночный объект-дескриптор, заключите инструкции, которые создают объект в if isempty() защита для постоянной переменной.
Например, рассмотрим класс mycls и функции usehandle2. Генератор кода сообщает об ошибке для usehandle2 потому что p.prop относится к mycls объект, что оператор inner = mycls создает. Этот оператор создает mycls объект для каждого вызова 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
При перемещении операторов inner = mycls и inner.prop = x внутри if isempty() защита, генерация кода выполняется успешно. Заявление inner = mycls выполняется только один раз в течение срока действия программы.
function usehandle2(x) assert(isa(x, 'double')); persistent p; if isempty(p) inner = mycls; inner.prop = x; p = mycls; p.prop = inner; end
Рассмотрим функцию usehandle3. Генератор кода сообщает об ошибке для usehandle3 потому что постоянная переменная p относится к mycls объект, что оператор myobj = mycls создает. Этот оператор создает mycls объект для каждого вызова 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
Если вы делаете myobj persistent и включить оператор myobj = mycls внутри if isempty() защита, генерация кода выполняется успешно. Заявление myobj = mycls выполняется только один раз в течение срока действия программы.
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
Рассмотрим функцию refHandle копирует свойство объекта дескриптора в другой объект. Функция использует простой класс дескриптора и класс значения. В MATLAB ® функция запускается без ошибок.
function [out1, out2, out3] = refHandle() x = myHandleClass; y = x; v = myValueClass(); v.prop = x; x.prop = 42; out1 = x.prop; out2 = y.prop; out3 = v.prop.prop; end
classdef myHandleClass < handle properties prop end end
classdef myValueClass properties prop end end
Во время создания кода возникает ошибка:
Property 'v.prop.prop' is undefined on some execution paths.
Три переменные ссылаются на одну и ту же ячейку памяти: x, y, и v.prop. Генератор кода определяет, что x.prop и y.prop использовать одно и то же значение. Генератор кода не может определить, что свойство объекта дескриптора v.prop.prop делится своим определением с x.prop и y.prop. Чтобы избежать ошибки, определите v.prop.prop непосредственно.