Main Content

事件和侦听程序概念

事件模型

事件表示对象内发生的变化或动作。例如,

  • 类数据的修改

  • 方法的执行

  • 查询或设置属性值

  • 对象的销毁

基本上,您可以通过编程方式检测到的任何活动都可以生成事件并将信息传递给其他对象。

MATLAB® 类定义过程,该过程将事件的发生通告给响应这些事件的其他对象。事件模型的工作原理如下:

  • 句柄类声明用于表示事件的名称。命名事件

  • 创建事件声明类的对象后,将侦听程序关联到该对象。Control Listener Lifecycle

  • 对句柄类的 notify 方法的调用会向侦听程序广播事件通知。类用户决定何时触发事件。触发事件

  • 侦听程序在得到通知事件已发生时执行回调函数。Specifying Listener Callbacks

  • 您可以将侦听程序绑定到定义事件的对象的生命周期,或者将侦听程序的工作范围限制为侦听程序对象的存在期限和作用域内。Control Listener Lifecycle

下图展示了事件模型。

Model of events and listeners

局限性

事件的使用有一些限制:

  • 事件源无法保证触发事件时侦听程序存在。

  • 一个侦听程序无法阻止其他侦听程序得到事件发生的通知。

  • 各侦听程序执行的顺序没有定义。

  • 侦听程序不应修改传递给侦听程序回调的事件数据对象,因为其他侦听程序传递的是同一个句柄对象。

默认事件数据

事件通过向回调函数传递事件数据参量来向侦听程序回调提供信息。默认情况下,MATLAB 向侦听程序回调传递一个 event.EventData 对象。该对象有两个属性:

  • EventName - 类 event 代码块中定义的事件名称

  • Source - 作为事件源的对象

MATLAB 在所需的事件数据参量中将源对象传递给侦听程序回调。使用源对象从侦听程序回调函数中访问对象的任何公共属性。

自定义事件数据

您可以创建 event.EventData 类的子类,为侦听程序回调函数提供附加信息。子类将定义包含附加数据的属性,并提供构造派生事件数据对象的方法,以便将其传递给 notify 方法。

定义特定于事件的数据提供说明如何自定义这些数据的示例。

事件仅在句柄类中

您只能在句柄类中定义事件。存在此限制是因为值类仅在单个 MATLAB 工作区中可见,因此没有回调或侦听程序可以访问触发事件的对象。回调可以访问对象的副本。但是,访问副本没有用,因为回调无法访问触发事件的对象的当前状态或在该对象中进行任何更改。

句柄类和值类的比较提供关于句柄类的一般信息。

事件和侦听程序语法说明定义句柄类和事件的语法。

属性 set 和查询事件

有四个与属性相关的预定义事件:

  • PreSet - 在设置属性值(调用其 set 访问方法)前即刻触发

  • PostSet - 设置属性值后即刻触发

  • PreGet - 在响应属性值查询(调用其 get 访问方法)前即刻触发

  • PostGet - 返回查询的属性值后即刻触发

这些事件是预定义的,不需要在类 events 代码块中列出。

发生属性事件时,将向回调传递 event.PropertyEvent 对象。该对象有三个属性:

  • EventName - 此数据对象描述的事件的名称

  • Source - 源对象,该对象的类定义数据对象描述的事件

  • AffectedObject - 事件的来源属性所属的对象,即 AffectedObject 包含属性被访问或修改的对象。

您可以通过子类化 event.EventData 类来定义自己的属性更改事件数据。event.PropertyEvent 类是 event.EventData 的密封的子类。

有关创建属性侦听程序的过程的描述,请参阅侦听对属性值的更改

有关示例,请参阅 The PostSet Event Listener

有关控制对属性值的访问的方法的信息,请参阅属性 get 和 set 方法

侦听程序

侦听程序封装对事件的响应。侦听程序对象属于 event.listener 类,这是句柄类,它定义以下属性:

  • Source - 生成事件的对象的句柄或句柄数组

  • EventName - 事件的名称

  • Callback - 当启用的侦听程序收到事件通知时执行的函数

  • Enabled - 回调函数仅在 Enabledtrue 时执行。有关示例,请参阅Enable and Disable Listeners

  • Recursive - 允许侦听程序再次触发之前导致回调执行的同一事件。

    默认情况下,Recursivefalse。如果回调触发的事件正是其自身所关联的事件,则侦听程序无法递归执行。因此,如果回调必须触发自身所关联的事件,请将 Recursive 设置为 true。将 Recursive 属性设置为 true 会造成无限递归达到递归极限并触发错误的情况。

Control Listener Lifecycle提供了更具体的信息。