Reputation: 345
I am trying to raise an event in Matlab. It is working, but not as i expected. What is going on is that the source object is passed as parameter do the event handler and i can't access my object properties inside the event handler.
Here is my class:
classdef MyClass < handle
properties
Name = 'a';
end
events
Changed
end
methods
function obj = MyClass(current)
if exist('current','var')
addlistener(current,'Changed',@ChangedHandle);
end
end
function obj = Change(obj,value)
notify(obj,'Changed');
end
function obj = ChangedHandle(obj,value)
disp(obj.Name);
end
end
end
These are the command lines to reproduce whats going on:
a = MyClass();
b = MyClass(a);
b.Name = 'b';
a.Change(3);
This is returning "a" and i want it to return "b".
Regards
Upvotes: 1
Views: 128
Reputation: 5672
In your addlistener
code you are not telling the listener
which object you want to call the method on, so what Matlab does it will apply the listener to the current
object since thats all that was passed into the function, you can check this by changing the code to:
addlistener(current,'Changed',@(h,evt)current.ChangedHandle);
if you want it to run the code for the other class b (obj)
, then you use:
addlistener(current,'Changed',@(h,evt)obj.ChangedHandle);
Upvotes: 1
Reputation: 1880
The listener callback you specify receives details of the object raising the event. The fact that the listener has been created during the creation of a different object is not an intrinsic property of the listener – unless you effectively embed this in the design of your callback.
In your example, @ChangedHandle
only works as a callback because it happens to be a method of the class current
belongs to. If a
and b
belonged to different classes the problem would be more obvious: if ChangedHandle
was a method only of a
, it wouldn't know anything about the Name
property of b
. And if only a method of b
, the listener bound to a
would have only the function handle without any reference to the instance b
of the class to which ChangeHandle
belongs.
As described in the listener callback documentation you can use a method of the specific object instance current
as an event listener using the syntax @current.ChangedHandle
.
This method then receives callback arguments in the format callbackMethod(obj,src,evnt)
, so you need to add an argument to the definition of ChangedHandle
. The first argument obj
will be the instance referenced by current
when the listener is created, so the line disp(obj.Name)
will then produce the intended result without modification.
The reference to a
received by the callback in the example will still be passed to the new callback – this is a fundamental behaviour of listener callbacks – but it will now be accessible from the second argument src
.
Upvotes: 1