我遇到了一些对我来说不熟悉的代码......
我从来没有真正看到过对象过程的类型声明,我只是没有 明白这一点。 为什么开发人员不能只保留Boolean类型的字段?
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.
答案 0 :(得分:18)
让我们将其分为两部分,以便更容易理解。首先,procedure(AFinished: Boolean)
不是boolean
变量,它是对以布尔值作为参数的过程的引用。它基本上是一个过程头,除了没有过程名,因为这只是一个类型定义。可以将与此签名匹配的任何过程分配给此变量。
of object
部分意味着这不仅仅是一个过程参考,而是一个方法参考;它必须属于一个对象。编译器需要知道差异,以便它可以将对象的self
指针与过程指针一起存储,以便可以正确调用它,正如其他海报所指出的那样。
基本上,这是声明一个新的事件处理程序,它在Delphi中是一种非常常见的模式。 VCL在整个地方做的事情都是一样的。创建按钮并分配OnClick
处理程序时,它必须是procedure (Sender: TObject) of object;
。您的表单为按钮提供了一个引用自身和事件处理程序过程的方法引用,然后当有人单击它时,该按钮使用该信息来调用表单上的处理程序。
这段代码做了同样的事情。它提供了一种方法,可以在运行DoUpdateMessage时通知某些外部对象,使用标准Delphi习惯用于事件通知。
答案 1 :(得分:12)
procedure of object
是类实例中包含的过程的过程参考。调用作为类成员的过程时,必须使用其他参数传递implict Self
引用。使用procedure of object
告诉编译器将过程引用中的过程地址存储在Self
引用中,这样当通过过程引用调用过程时,Self
引用将自动传递
在您提供的代码段中,TFinishedCaptureEvent
被定义为对象的过程,这意味着其类型创建的任何变量将包含2个值:Self
值和过程地址。分配此变量时,特别是当赋值在类中时,编译器将自动将此变量内的Self值设置为包含分配给变量的过程的类的实例。调用变量(FOnFinishedCapture(False)
)时,编译器会自动将正确的Self
值传递回分配给此变量的过程。
答案 2 :(得分:2)
我不明白你如何将它与布尔字段相关联。
但是TFinishedCaptureEvent = procedure(AFinished: Boolean) of object
声明了一个委托/方法指针类型,用于事件。它是record
,包含self
指针和函数指针。当您调用委托时,将调用该函数,并将self
作为参数传递给函数。