MATLAB-涉及侦听器时对象析构函数未运行 [英] MATLAB - object destructor not running when listeners are involved

查看:121
本文介绍了MATLAB-涉及侦听器时对象析构函数未运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类,PlantGenerator. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆