Matlab onCleanup 函数未执行

标签 matlab

我在 MATLAB R2013a 中遇到了以下问题,出于某种我不明白的原因,当在函数中定义了计时器(包括 TimerFcn)时,它不会调用 onCleanup 函数。

我添加了两个显示问题的最小示例:

首先是按预期调用清理例程的工作版本:

function mytest(time)
  t = timer();
  myclean = onCleanup(@() disp('function ended'));
  pause(time);
end

现在是不调用清理的错误版本(无论是在函数正常结束时还是在按下 ctrl+c 时)

function mytest2(time)
  t = timer();
  t.TimerFcn = @(o,s)disp(' ... waiting for some time'); 
  myclean = onCleanup(@() disp('function ends'));
  pause(time);
end

我在文档中找不到任何提示,为什么定时器或更具体的 TimerFcn 定义会改变清理代码的执行?

最佳答案

哎呀 - 这太讨厌了。它不是错误,但它肯定不是您从文档中期望的,也不是您想要的。幸运的是,它很容易变通。

首先,发生了什么?

好吧,onCleanup 返回一个 onCleanup 对象。这是一个对象,其唯一目的是将析构函数方法设置为您的 @() disp('function ends')。当对象超出范围时(您希望它位于函数 mytest2 的末尾),它会被删除,它的析构函数方法会执行,并且您的消息会显示出来。我认为这就是您所期望的。

但是当你创建匿名函数@(o,s)disp(' ... waiting for some time'),并将其赋值给的TimerFcn你的计时器,它需要函数 mytest2 的整个当前工作区的副本,包括 onCleanup 对象。计时器是在基础工作区(而不是函数工作区)中创建的,并且即使在函数结束时仍然存在,以及 onCleanup 对象,它永远不会超出范围,永远不会获取已删除,其析构函数永远不会运行,您也不会收到消息。

注意:

  1. 如果你运行 a = timerfindall; delete(a); 在基础工作区中,您将收到消息,因为您已经明确删除了计时器以及 onCleanup 对象。
  2. 这种关于匿名函数获取其整个工作区的副本的行为已被完整记录,尽管您可能没有意识到,并且您显然不希望它在这里这样工作。这很讨厌。

幸运的是,它很容易变通:

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 对象超出您预期的范围,一切正常。

希望对您有所帮助!

关于Matlab onCleanup 函数未执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22898001/

相关文章:

c++ - 如何在我的代码中使用 Matlab 引擎(用于调用 `engOpenSingleUse()` )?

Matlab:如何对不包括NaN的数据下降进行排序

c++ - Eigen Library - EigenSolver 中的复数值

当值为零时,Matlab 线图与轴重叠

matlab - 检测时间扩散回波

Matlab:如何使用 for 循环在结构中创建多个字段

string - 如何将工作区变量名称与字符串列表(元胞数组)进行比较?

matlab - 如何在matlab中绘制坡度场

matlab - 凸随机值的最小化

matlab - MATLAB 标题的不同部分使用不同的颜色