I have two classes, Plant
and Generator
. Generator
creates a vector and broadcasts it via notify()
, which Plant
Perhaps I'm resurrecting a 2 year old question, but...
Matlab wants to call the destructor on clear; the problem is in how you've defined your listener. You defined it as:
obj.plant.Listener = addlistener(obj, 'newSignal', ...
@(src, data) obj.plant.ListenerCallback(data));
In doing so, you've created an anonymous function that has a hardcoded reference to obj. When obj goes out of scope elsewhere (e.g. via clearing in the base workspace), it still continues to exist in your anonymous function. If you instead define:
obj.plant.Listener = addlistener(obj, 'newSignal', ...
@(src, data) src.plant.ListenerCallback(data));
there's no hardcoded references in the anonymous function. The first argument to the listener callback is always the object it was invoked from, but you get it on the fly rather than hardcoding an object reference in an anonymous function.
Hope this is still of some value to you!
Why is the destructor called at such weird times?
clear G #% DESTRUCTOR NOT CALLED??
There is still a reference to G
in the listener of P
G = Generator(P)
Generator instance deleted #% why is the destructor run now?
As the new Generator
is instantiated, the listener gets overwritten. This calls the destructor of the first instance of Generator
, since there is no longer any reference to it.
G =
Generator handle
Properties:
plant: [1x1 Plant]
Methods, Events, Superclasses
>> clear G
Generator instance deleted #% and why is the destructor run properly now?
Let's look again what happened in the previous step: (1) The listener of plant
gets overwritten with the new Generator
. (2) This calls the destructor of the first Generator
. (3) The destructor clears the listener of plant
(!!!) (4) G
in the workspace is now the last remaining instance of the new Generator
. Thus, clear G
calls the class destructor.
One not-pretty way that would allow you to use clear
instead of delete
would be to overload the clear
command
function clear(varargin)
%# check for Generator objects
isGenerator = cellfun(@(x)evalin('caller','isa(x,''Generator'');'),varargin);
%# I loop here b/c I don't have the time to carefully construct
%# the evalin commands
%# Generator gets deleted, everybody else gets cleared
for i=1:nargin
if isGenerator(i)
evalin('caller',sprintf('delete %s',varargin{i}));
else
evalin('caller',sprintf('builtin(''clear'',''%s'');',varargin{i});
end
end