哎哟 – 这很讨厌.这不是一个错误,但它肯定不是你对文档的期望,它不是你想要的.幸运的是,它很容易解决.
首先,发生了什么?
好吧,onCleanup返回一个onCleanup对象.这是一个对象,其唯一目的是将析构函数方法设置为@()disp(‘function ends’).当对象超出范围(您希望在函数mytest2的末尾)时,它将被删除,执行析构函数方法,并显示您的消息.我想这就是你所期望的.
但是当您创建匿名函数@(o,s)disp(‘…等待一段时间’),并将其分配给计时器的TimerFcn时,它会获取函数mytest2的整个当前工作空间的副本,包括onCleanup对象.计时器是在基础工作区(而不是函数工作区)中创建的,并且即使在函数结束时仍然存在,并且onCleanup对象随后永远不会超出范围,永远不会被删除,它的析构函数永远不会运行,你没有收到你的消息.
注意:
>如果你运行= timerfindall;删除的(a);在基本工作区中,您将获得您的消息,因为您已明确删除了计时器以及onCleanup对象.
>关于匿名函数获取整个工作区副本的这种行为已经完整记录,尽管您可能没有意识到这一点,尽管您显然不希望它在此处工作.这很讨厌.
幸运的是,它很容易解决:
function mytest3(time)
t = timer();
setTimerFcn(t)
myclean = onCleanup(@() disp('function ends'));
pause(time);
end
function setTimerFcn(t)
t.TimerFcn = @(o,s)disp(' ... waiting for some time');
end
现在,当创建匿名函数时,它只需要一个本地工作空间的副本(即来自子函数setTimerFcn),它不包含onCleanup对象. onCleanup对象超出了你期望的范围,一切都很好.
希望有所帮助!