请解释一下:Delphi中的 type... procedure of object 是什么意思?

11

我遇到了一些对我来说比较新的代码......

我从来没有真正看到过procedure of object的类型声明,而且我也不明白这样做有什么意义。 为什么开发人员不能简单地保留一个布尔类型的字段呢?

interface

    type
      TFinishedCaptureEvent = procedure(AFinished: Boolean) of object;

      TFrameCard = class(TFrame)
      ...
      private
        FOnFinishedCapture: TFinishedCaptureEvent;
        procedure DoUpdateMessage(AMessageType: TMessageType);
      public
        property OnFinishedCapture: TFinishedCaptureEvent read FOnFinishedCapture write FOnFinishedCapture;
      end;    

implementation

...

procedure TFrameCard.DoUpdateMessage(AMessageType: TMessageType);
begin
  if Assigned(FOnFinishedCapture) then
    FOnFinishedCapture(False);
  ...
end;

end.

1
谢谢到目前为止的答案,但它们对我来说太学术化了。你能用我能理解的方式来解释吗?开发人员本可以声明一个布尔属性,该属性读写表单/窗体的布尔字段。 - Richard Woolf
2
@Richard 如果将其作为属性完成,那么它将否认多线程的机会,更重要的是,它将强制客户端(提供事件处理程序的对象)对触发事件的对象有深入的了解。 - David Heffernan
谢谢,我觉得我现在开始明白了 :) - Richard Woolf
1
为了更加清晰明了,这里的真正好处是当TFrameCard中(也许是漫长的)过程完成它正在做的任何事情时,客户端应用程序可以立即收到通知,同时被通知AFinished参数的值。 - Stuart
@Stuart 谢谢,我已经开始怀疑这样的事情了... 我有一个 TForm(TFormSales),其中包含一个 Frame(TFrameCard),该 Frame 还具有一个 Frame(TFrameCardList)。TFrameCardList 使用此功能向 TFrameCard 发送消息。 TFrameCard 反过来设置此 FOnFinishedCapture 属性。 现在,我必须让 TFormSales 获取此消息。 今天我学到了一些东西,虽然还不是150%清楚,但我认为这是我需要更深入理解的东西... - Richard Woolf
3个回答

21

为了更容易理解,我们将其分为两个部分。首先,procedure(AFinished: Boolean)并不是一个boolean变量,它是一个引用一个以布尔值为参数的过程的指针。它基本上是一个过程头,但没有过程名称,因为这只是一个类型定义。任何符合这个签名的过程都可以被分配给这个变量。

of object部分意味着这不仅仅是一个过程引用,而是一个方法引用;它必须属于一个对象。编译器需要知道区别,以便将self指针与过程指针一起存储,以便可以正确调用,正如其他帖子中所指出的那样。

基本上,这声明了一个新的事件处理程序,这是Delphi中非常常见的模式。这就是VCL在各个地方都做的事情。当您创建一个按钮并分配一个OnClick处理程序时,它必须是一个procedure(Sender: TObject) of object;。您的表单为按钮提供了一个引用自身和事件处理程序的方法引用,然后当有人单击它时,按钮使用这些信息在表单上调用处理程序。

这段代码正在执行相同的操作。它提供了一种方式,让某些外部对象在运行DoUpdateMessage时得到通知,使用标准的Delphi事件通知习惯。


13
procedure of object是指包含在类实例中的过程引用,用于调用属于类的成员的过程。在调用类成员的过程中,需要将隐式的Self引用与其他参数一起传递。使用procedure of object告诉编译器将Self引用与过程地址一起存储在过程引用中,这样当通过过程引用调用过程时,Self引用将自动传递。
在您提供的代码片段中,TFinishedCaptureEvent被定义为一个对象的过程,这意味着任何创建其类型的变量都将包含两个值:Self值和过程地址。当此变量被分配时,特别是当分配在类内部时,编译器将自动设置此变量中的Self值为包含被赋给该变量的过程的类的实例。当调用该变量(FOnFinishedCapture(False))时,编译器会自动将正确的Self值传递回被分配给该变量的过程。

谢谢,我想我现在开始明白了 :) - Richard Woolf

3
我不明白你如何将此与布尔领域相关联。
但是,TFinishedCaptureEvent = procedure(AFinished: Boolean) of object 声明了一个委托/方法指针类型,用于事件。它是一个包含 self 指针和函数指针的 record。当你调用委托时,函数将被调用,并将 self 作为参数传递给函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接