它在语法上可能是正确的,但侦听器回调永远不会执行。例子:
classdef MyClass < handle
properties (Access = public)
a
end
properties (SetAccess = private, Dependent, SetObservable)
b
end
methods
function val = get.b(this)
val = this.a;
end
end
end
Now try:
c = MyClass();
lh = addlistener(c, 'b', 'PostSet',@(o,e)disp(e.EventName));
c.a = 1;
disp(c.b)
正如您所看到的,“PostSet”回调从未执行。
EDIT
在我看来,SetObservable
确实应该设置为a
not b
。这是因为b
是只读的并且只能在以下情况下更改a
变化。现在PostSet
事件会通知我们两个属性都已更改。
使用我上面使用的相同示例,只需移动SetObservable
from b
to a
。当然,现在您可以按照以下方式收听该事件:
lh = addlistener(c, 'a', 'PostSet',@(o,e)disp(e.EventName));
EDIT#2
抱歉,我没有注意到您有复合的事实(类有一个 A 类的实例作为私有财产)。
考虑这个可能的解决方案:
AClass.m
classdef AClass < handle
properties (SetObservable)
a %# observable property
end
end
BClass.m
classdef BClass < handle
properties (Access = private)
aClassInst %# instance of AClass
lh %# event listener on aClassInst.a
end
properties (Dependent, SetAccess = private)
b %# dependent property, read-only
end
events (ListenAccess = public, NotifyAccess = private)
bPostSet %# custom event raised on b PostSet
end
methods
function this = BClass(aClass)
%# store AClass instance handle
this.aClassInst = aClass;
%# listen on PostSet event for property a of AClass instance
this.lh = addlistener(this.aClassInst, 'a', ...
'PostSet', @this.aPostSet_EventHandler);
end
function val = get.b(this)
val = this.aClassInst.a;
end
end
methods (Access = private)
function aPostSet_EventHandler(this, src, evt)
%# raise bPostSet event, notifying all registered listeners
notify(this, 'bPostSet')
end
end
end
基本上我们设置属性a
A 类可观察到的。
接下来,在 Class 的构造函数中,我们为传递来侦听属性的 A Class 实例注册一个侦听器a
变化。在回调中,我们通知该对象的侦听器b
也改变了
因为我们无法真正筹集到PostSet
手动,我创建了一个自定义事件bPostSet
我们在前面的回调函数中提出了这一点。您始终可以自定义传递的事件数据,请参阅文档 http://www.mathworks.com/help/techdoc/matlab_oop/brb6gnc.html#brb6i_k看看如何。
这是一个测试用例:
%# create the objects
a = AClass();
b = BClass(a);
%# change property a. We will not recieve any notification
disp('a.a = 1')
a.a = 1;
%# now lets listen for the 'bChanged' event on b
lh = addlistener(b, 'bPostSet',@(o,e) disp('-- changed'));
%# try to change the property a again. We shall see notification
disp('a.a = 2')
a.a = 2;
%# remove event handler
delete(lh)
%# no more notifications
disp('a.a = 3')
a.a = 3;
输出是:
a.a = 1
a.a = 2
-- changed
a.a = 3
请注意,当我们注册侦听器时,我们如何仅与 BClass 实例进行交互。当然,因为所有类都派生于handle
类、实例a
和私有财产aClassInst
两者都引用同一个对象。所以任何改变a.a
立即反映出来b.aClassInst.a
,这导致内部aPostSet_EventHandler
执行,这又通知所有注册的侦听器我们的自定义事件。