MATLAB-涉及计时器时无法清除对象 [英] MATLAB - objects not clearing when timers are involved

查看:287
本文介绍了MATLAB-涉及计时器时无法清除对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这与这个问题有些相关,但不完全相同.

This is somewhat related to this question, but not quite.

我有两个类,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

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

Say I execute the following code in the Command Window:

>> 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的丑陋而直接的解决方法来重载clear命令,那么有一种方法可以从工作空间中clear T ?此外,什么都没有引用T,那么为什么存在对它的引用呢? (从来没有调用析构函数的事实暗示了这一事实.)这是否埋在计时器对象本身中?

What's going on here? I know that timer objects need to be manually deleted, but I thought that would be dealt with in the destructor for TimerWrapper. Without using Amro's ugly but straightforward workaround to overload the clear command, is there a way to clear T from the workspace? Furthermore, nothing is referring to T, so why does a reference to it exist? (The fact that the destructor is never called implies this fact.) Is this buried in the timer object itself?

推荐答案

如果键入t = TimerWrapper; f = functions(t.Timer.TimerFcn); f.workspace(2),则会看到用于回调的匿名函数的工作区包含对TimerWrapper对象本身的引用.因此,存在一种clear未采用的循环引用.

If you type t = TimerWrapper; f = functions(t.Timer.TimerFcn); f.workspace(2), you'll see that the workspace of the anonymous function used for the callback contains a reference to the TimerWrapper object itself. So there's a kind of circular reference there which is not picked up by clear.

鉴于您如何进行设置,可以通过显式调用析构函数然后调用clear来删除T(及其底层的计时器对象).

Given how you've set things up, you can remove T (and its underlying timer object) by calling the destructor explicitly and then calling clear.

T.delete
clear T

cleardelete之间的区别有点令人困惑(无论如何,对我而言).如您所见,clear并未明确调用析构函数.它只是从工作区中删除名称 T.因此,此时T及其底层计时器仍然存在.如果它们不包含对仍然存在的事物的引用,则MATLAB将正确删除T,包括调用其析构函数.实际上,由于计时器包含对T的引用(在其回调中),该引用仍然存在,因此不会删除计时器(因此也包括T).

The difference between clear and delete is kind of confusing (to me, anyway). As you've found, clear doesn't explicitly call the destructor. It just removes the name T from the workspace. So T, and its underlying timer, still exist at that point. If they contained no references to things that still existed, MATLAB would then remove T properly, including calling its destructor. As it is, since the timer contains a reference (in its callback) to T, which still exists, the timer (and thus T as well) is not deleted.

您可以使用timerfindall找到它(尽管在工作空间中没有名称),并且如果您自己使用显式删除它,则可以使用

You can find it (despite not having a name in the workspace) with timerfindall, and if you explicitly delete it yourself using

tmrs = timerfindall;
delete(tmrs);

您会发现T现在已正确消失.

you'll find that T is now properly gone.

我不确定这是一个错误,尽管我觉得它很混乱,并且cleardelete之间的区别可能会得到更好的记录.

I'm not so sure that this is a bug, although I find it pretty confusing, and the distinction between clear and delete could probably be documented better.

关于变通方法,我发现显式调用delete并不麻烦,尽管如果不小心调用clear则清理起来要麻烦得多.我认为您链接到的线程中消息5中的建议,而不是消息#4,它会更通用,更健壮.

As to a workaround, I don't find it a big pain to explicitly call delete, although it's a bit more of a pain to clean things up if you accidentally call clear. I would think the suggestion in message #5 from the thread you linked to, rather than message #4, would be more general and robust.

我不认为您应该在链接的单独线程中以@Amro 建议的方式重载clear到:尽管如果您显式调用clear T可能会起作用,但是如果调用clear allclear variables仍可能会遇到麻烦. (我现在还没有尝试过,但是我相信clear的这些语法甚至不会循环工作区中的内容并在每个工作区上调用clear-而是它们调用内部MATLAB工作区的clear方法对象,这很快就会令人困惑).

I don't think you should overload clear in the way @Amro suggests in the separate thread you linked to: although this may work if you call clear T explicitly, you may still get into trouble if you call clear all, or clear variables. (I haven't tried it just now, but I believe these syntaxes of clear don't even loop over things in the workspace and call clear on each - instead they call the clear method of the internal MATLAB workspace object, and that's going to get confusing fast).

这篇关于MATLAB-涉及计时器时无法清除对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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