matlab - 当对象的方法之一用作其自身属性的回调时,如何调用对象的析构函数?

标签 matlab oop

我正在尝试编写一个围绕 serial 端口读取传感器的类:

classdef sensor < handle
    properties
        Value
        s
    end

    methods
         function obj = sensor(port)
             obj.s = serial(port);
             obj.s.BytesAvailableFcn = @(o,e) obj.getData;

             fopen(obj.s);
         end
         function delete(obj)
             disp('called destructor');
             try
                 fclose(obj.s);
                 delete(obj.s);
             end
          end
          function getData(obj)
              obj.Value = fscanf(obj.s, '%d');
          end
     end
end

当我尝试清除工作区时,从未调用析构函数:

>> foo = sensor('COM1');
>> clear foo % should disp() something!

基于我的 previous experiences ,仍然必须有对 foo 的引用。原来这是嵌入在串行端口 foo.s 中:

>> ports = instrfindall;
>> ports.BytesAvailableFcn
ans = 
    @(o,e)obj.getData

一旦我清除了 BytesAvailableFcn,即

>> ports.BytesAvailableFcn = '';

然后 clear all,我显示了我的调用的析构函数

我怎样才能打破这个循环引用并让我的析构函数被调用?如果未调用析构函数,串行端口将保持绑定(bind)状态。

最佳答案

问题不完全在于你有一个循环引用;理论上,MATLAB 应该捕捉到这些。问题是循环引用通过 Java 进行,而 MATLAB 无法捕获它。

更详细地说 - 您的 serial 对象在内部包含一个 Java 对象,它是捕获到串行端口连接的真实对象。当您设置其回调时,MATLAB 会设置底层 Java 对象的回调。如果回调是针对包含串行对象作为属性的对象的方法,那么您就有了一个通过底层 Java 对象的循环引用。当您调用 clear 时,MATLAB 会检查循环引用,如果它们都在 MATLAB 中,它会捕获它们并调用析构函数 - 但它不会在通过 Java 时捕获它们。

一种解决方案是显式调用析构函数,也许这不会太麻烦。

另一种解决方法可能是简单地将回调作为类的方法 - 也许它可以只是一个常规函数,因为它似乎不需要任何信息来自主对象本身而不是对串行对象的引用。如果您希望将所有代码保存在一个文件中,也许您可​​以将其创建为匿名函数(但要小心,因为匿名函数将捕获它创建的工作空间,这取决于您创建它的位置可能包括对主对象的引用,在这种情况下,您将再次获得循环引用。

编辑:罗迪说得对 - 抱歉,我读问题的速度太快,没有注意到 getData 实际上设置了 Value 属性而不仅仅是返回数据。罗迪在他的回答中的解决方案可能是另一种解决方法,但就像他说的那样 - 讨厌。我只是手动调用 delete

关于matlab - 当对象的方法之一用作其自身属性的回调时,如何调用对象的析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24189308/

相关文章:

linux - Matlab 中的 AlphaData 替代方案

matlab - 如何在不使用预定义函数的情况下绘制声音文件的频谱图?

Python OOP 实例和类的可变性

java - 将组合框和JLabel数组、图片绑定(bind)在一起

oop - 类属性声明: private vs public

matlab - 在 Matlab 中打印行号

matlab - 使用matlab从实数截取整数

c++ - 同步 MATLAB 和 C++

c++ - 是否可以继承接口(interface)的实现

c++ - PIMPL 成语真的在实践中使用吗?