Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop MATLAB-当涉及侦听器时,对象析构函数未运行_Oop_Matlab_Destructor_Handle - Fatal编程技术网

Oop MATLAB-当涉及侦听器时,对象析构函数未运行

Oop MATLAB-当涉及侦听器时,对象析构函数未运行,oop,matlab,destructor,handle,Oop,Matlab,Destructor,Handle,我有两门课,Plant和GeneratorGenerator创建一个向量,并通过notify()进行广播,后者Plant监听。下面是classdef。请注意,我没有包括实际的数据生成方法,因为它与我的问题无关 classdef Plant < handle properties Listener end methods function ListenerCallback(obj, data) #% Per

我有两门课,
Plant
Generator
Generator
创建一个向量,并通过
notify()
进行广播,后者
Plant
监听。下面是classdef。请注意,我没有包括实际的数据生成方法,因为它与我的问题无关

classdef Plant < handle
    properties
         Listener
    end
    methods
         function ListenerCallback(obj, data)
             #% Perform an operation on data
         end
    end
end

classdef Generator < handle
    properties
        plant
    end
    events
        newSignal
    end
    methods
        function obj = Generator(plant)
            obj.plant = plant;
            obj.plant.Listener = addlistener(obj, 'newSignal', ...
                @(src, data) obj.plant.ListenerCallback(data));
        end
        function delete(obj)
            delete(obj.plant.Listener);
            disp('Generator instance deleted');
        end
    end
end
我的析构函数每次运行都很重要。这里发生了什么,如何让析构函数正常工作?(如果这不起作用,我可能会完全删除侦听器,直接从
生成器
实例调用
Plant.ListenerCallback()


编辑:看起来,当我执行
清除G
时,变量
G
将从工作区中删除-但
生成器
对象仍保留在
p.Listener.Source
中。这就是为什么没有调用析构函数。所以我想没有办法通过删除
G
来摆脱
P.Listener
。。有没有办法让这个函数实现我想要的功能,或者我只是被卡住了?

为什么在如此奇怪的时间调用析构函数

clear G #% DESTRUCTOR NOT CALLED??
p

G = Generator(P)
Generator instance deleted #% why is the destructor run now?
当新的
生成器
被实例化时,侦听器将被覆盖。这将调用
生成器的第一个实例的析构函数,因为不再有对它的任何引用

G = 
  Generator handle

  Properties:
    plant: [1x1 Plant]
  Methods, Events, Superclasses
>> clear G
Generator instance deleted #% and why is the destructor run properly now?
让我们再看看上一步中发生了什么:(1)新的
生成器将覆盖
plant
的侦听器。(2) 这将调用第一个
生成器的析构函数。(3) 析构函数清除工作区中
plant
(!!!)(4)
G
的侦听器现在是新
生成器的最后一个剩余实例。因此,
clear G
调用类析构函数


允许您使用
clear
而不是
delete
的一种不太好的方法是重载
clear
命令

function clear(varargin)

%# check for Generator objects
isGenerator = cellfun(@(x)evalin('caller','isa(x,''Generator'');'),varargin);

%# I loop here b/c I don't have the time to carefully construct
%# the evalin commands
%# Generator gets deleted, everybody else gets cleared
for i=1:nargin
   if isGenerator(i)
      evalin('caller',sprintf('delete %s',varargin{i}));
   else
      evalin('caller',sprintf('builtin(''clear'',''%s'');',varargin{i});
   end
end

也许我在重复一个2年前的问题,但是

Matlab希望调用clear上的析构函数;问题在于你如何定义你的听众。您将其定义为:

 obj.plant.Listener = addlistener(obj, 'newSignal', ...
                @(src, data) obj.plant.ListenerCallback(data));
在这样做的过程中,您创建了一个匿名函数,该函数具有对obj的硬编码引用。当obj在其他地方超出范围时(例如通过在基本工作区中清除),它仍然存在于匿名函数中。如果您改为定义:

 obj.plant.Listener = addlistener(obj, 'newSignal', ...
            @(src, data) src.plant.ListenerCallback(data));
匿名函数中没有硬编码引用。侦听器回调的第一个参数始终是从中调用它的对象,但是您可以动态获取它,而不是在匿名函数中硬编码对象引用


希望这对你还是有价值的

尝试
删除G;清除G
而不是仅清除G
?从文档中,“您可以清除图形或其他对象的句柄,但这不会删除对象本身。使用“删除”删除对象和文件。删除对象不会删除用于存储其句柄的变量(如果有)。@tmpearce-确实有效。我只希望使用
clearg
,因为这段代码是一个更大的代码库的一部分。与我一起工作的大多数使用MATLAB的人都不知道
delete
clear
之间有什么区别,所以这可能会让人很困惑。是的,我理解。您可能希望使用此信息更新您的问题,因为析构函数没有问题,而是对象上的
clear
有问题。此外,请查看前一个问题以了解更多信息:@strictlyrude27:请参阅下面我编辑的答案。简短回答:这是一个很好的解释。丑陋但直截了当的解决方法。一如既往地感谢您,先生。对于类事件来说,这是一个很好的解决方案,但不幸的是,对于独立于类的计时器回调或串行事件来说,这不是一个很好的解决方案。
 obj.plant.Listener = addlistener(obj, 'newSignal', ...
            @(src, data) src.plant.ListenerCallback(data));