MATLAB-涉及计时器时无法清除对象 [英] MATLAB - objects not clearing when timers are involved
问题描述
这与这个问题有些相关,但不完全相同.
This is somewhat related to this question, but not quite.
我有两个类,FunctionWrapper
和TimerWrapper
:
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
clear
和delete
之间的区别有点令人困惑(无论如何,对我而言).如您所见,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.
我不确定这是一个错误,尽管我觉得它很混乱,并且clear
和delete
之间的区别可能会得到更好的记录.
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 all
或clear 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屋!