MATLAB - 涉及定时器时不清除的对象

时间:2012-05-07 22:27:47

标签: oop matlab timer

这与this question有些相关,但并不完全相同。

我有两个班级,FunctionWrapperTimerWrapper

classdef FunctionWrapper < handle
    methods
        function Fcn(obj)
            disp('FunctionWrapper.Fcn was called!');
        end
    end
end

classdef TimerWrapper < handle
    properties
        Timer
    end

    methods
       function obj = TimerWrapper(other_object)
            obj.Timer = timer;
            set(obj.Timer, 'Period', 1);
            set(obj.Timer, 'ExecutionMode', 'fixedSpacing');
            set(obj.Timer, 'TimerFcn', @(event, data) other_object.Fcn);
       end

       function start(obj)
           start(obj.Timer);
       end

       function stop(obj)
           stop(obj.Timer);
       end

       function delete(obj)
           disp('destructor called!');
           delete(obj.Timer);
       end
    end
end

假设我在命令窗口中执行以下代码:

>> F = FunctionWrapper;
>> T = TimerWrapper(F);
>> clear T %# T's destructor not called
>> timerfind %# just to verify that no, the destructor was never called

   Timer Object: timer-1

   Timer Settings
      ExecutionMode: fixedSpacing
             Period: 1
           BusyMode: drop
            Running: off

   Callbacks
           TimerFcn: @(event,data)other_object.Fcn
           ErrorFcn: ''
           StartFcn: ''
            StopFcn: ''

这里发生了什么?我知道需要手动删除timer个对象,但我认为这将在TimerWrapper的析构函数中处理。不使用Amro's ugly but straightforward workaround to overload the clear command,是否有办法从工作区clear T?此外,没有任何内容涉及T,那么为什么存在对它的引用呢? (从不调用析构函数的事实暗示了这一事实。)这是否隐藏在计时器对象本身中?

2 个答案:

答案 0 :(得分:2)

如果键入t = TimerWrapper; f = functions(t.Timer.TimerFcn); f.workspace(2),您将看到用于回调的匿名函数的工作空间包含对TimerWrapper对象本身的引用。所以那里有一种循环引用,clear没有找到它。

考虑到你如何设置,你可以通过显式调用析构函数然后调用T来删除clear(及其底层计时器对象)。

T.delete
clear T

cleardelete之间的差异让我感到困惑(无论如何)。如您所见,clear未明确调用析构函数。它只是从工作区中删除名称 T。因此T及其基础计时器在此时仍然存在。如果它们不包含对仍然存在的东西的引用,那么MATLAB将正确删除T,包括调用它的析构函数。实际上,由于计时器包含一个仍然存在的T引用(在其回调中),因此不会删除计时器(以及T)。

您可以使用timerfindall找到它(尽管工作区中没有名称),如果您使用

明确删除它
tmrs = timerfindall;
delete(tmrs);

你会发现T现已正常消失。

我不太确定这是一个错误,虽然我觉得它很混乱,cleardelete之间的区别可能会更好地记录下来。

至于解决方法,我没有发现明确调用delete是一件很大的痛苦,尽管如果你不小心打电话给clear,清理一下会有点痛苦。我认为你链接到thread的消息#5中的建议,而不是消息#4,会更加通用和健壮。

我认为你不应该在你链接到的单独主题中以@Amro suggests的方式重载clear:虽然如果你明确地调用clear T这可能会有效,但你可以如果您拨打clear allclear variables,仍会遇到麻烦。 (我刚才没有尝试过,但我相信clear的这些语法甚至不会循环工作区中的内容并在每个上调用clear - 而是调用clear内部MATLAB工作空间对象的方法,这将很快混淆。)

答案 1 :(得分:0)

好像这可能是因为计时器的回调设置为非默认值。 A proposed workaround(参见链接线程的消息#4)仅在调用start方法时设置回调函数,然后在调用stop方法时将其设置为null。 / p>