MATLAB-涉及侦听器时对象析构函数未运行 [英] MATLAB - object destructor not running when listeners are involved
问题描述
我有两个类,Plant
和Generator
. Generator
创建一个矢量,并通过notify()
进行广播,Plant
会监听该矢量. classdef在下面.请注意,我没有包括实际的数据生成方法,因为它与我的问题无关.
I have two classes, Plant
and Generator
. Generator
creates a vector and broadcasts it via notify()
, which Plant
listens for. The classdefs are below. Note that I didn't include the actual data-generation method because it's irrelevent to my question.
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
我注意到Generator
析构函数的行为确实很奇怪:我第一次创建然后删除Generator
实例时,它直到第二次创建Generator
实例时才运行析构函数.这是一个示例:
I noticed that the Generator
destructor behaves really oddly: the first time I create then delete a Generator
instance, it does not run the destructor until the second time I create the Generator
instance. Here's an example:
>> P = Plant
P =
Plant handle
Properties:
Listener: []
Methods, Events, Superclasses
>> G = Generator(P)
G =
Generator handle
Properties:
plant: [1x1 Plant]
Methods, Events, Superclasses
>> clear G #% DESTRUCTOR NOT CALLED??
>> 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?
我的析构函数每次运行都非常重要.这是怎么回事,我如何才能使析构函数正常运行? (如果无法解决,我可能会完全删除监听器,并直接从Generator
实例调用Plant.ListenerCallback()
.)
It's pretty important that my destructor runs every time. What is going on here, and how can I get the destructor to operate properly? (I might just remove the listener altogether and directly call Plant.ListenerCallback()
from the Generator
instance if this doesn't work out.)
编辑:看起来当我执行clear G
时,变量G
从工作空间中删除-但是Generator
对象位于P.Listener.Source
中.这就是为什么不调用析构函数的原因.所以我想没有办法通过删除G
来摆脱P.Listener
.是否有任何方法可以使它执行我想要的工作,或者我只是被卡住了?
EDIT: Looks like when I do clear G
, the variable G
is removed from the workspace - but the Generator
object lives on in P.Listener.Source
. This is why the destructor isn't being called. So I guess there's no way to get rid of P.Listener
by deleting G
.. is there any way to get this to do what I want or am I just stuck?
推荐答案
为什么在如此奇怪的时间调用析构函数?
Why is the destructor called at such weird times?
clear G #% DESTRUCTOR NOT CALLED??
在P
G = Generator(P)
Generator instance deleted #% why is the destructor run now?
在实例化新的Generator
时,侦听器将被覆盖.这将调用Generator
的第一个实例的析构函数,因为不再有对其的引用.
As the new Generator
is instantiated, the listener gets overwritten. This calls the destructor of the first instance of Generator
, since there is no longer any reference to it.
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
的侦听器被新的Generator
覆盖. (2)这将调用第一个Generator
的析构函数. (3)析构函数清除plant
(!!!)的侦听器(4)现在,工作空间中的G
是新Generator
的最后一个剩余实例.因此,clear G
调用类析构函数.
Let's look again what happened in the previous step: (1) The listener of plant
gets overwritten with the new Generator
. (2) This calls the destructor of the first Generator
. (3) The destructor clears the listener of plant
(!!!) (4) G
in the workspace is now the last remaining instance of the new Generator
. Thus, clear G
calls the class destructor.
一种允许您使用clear
而不是delete
的漂亮方法是重载clear
命令
One not-pretty way that would allow you to use clear
instead of delete
would be to overload the clear
command
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
这篇关于MATLAB-涉及侦听器时对象析构函数未运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!