gpt4 book ai didi

Delphi 叠瓦式回调函数

转载 作者:行者123 更新时间:2023-12-03 19:49:24 24 4
gpt4 key购买 nike

我有以下情况。

我做了一个组件。当我使用一种方法时,我想从组件中获得一些反馈。

像 component.Method(param1 : 回调函数);

到目前为止一切都很好而且有光泽。

该项目有以下单位。

formMain - 可见表单。

dataModule - 使用组件。

form main 需要传递给datamodule一个回调函数来接收他的反馈。此回调函数与组件不同(具有更多参数)。

我不知道该怎么做。

TFeedBackProcedure = procedure(param1 : Integer) of object;
TFeedBackProcedureByTypeOf = procedure(aTypeOf : Integer; param1 : Integer) of object;

// component
procedure Syncro(feedBack : TFeedBackProcedure);
begin
//somewhere inside
for i := 0 to 15 do begin
feedBack(i);
end;
end;
// the feeedback received so far when someone use the Syncro procedure is the value of i

// the datamodule
// inside of a method I need to pass also the i received from compoent also a typeof value used only inside datamodule
procedure UseMethod(feedbackProcedure : TFeedBackProcedureByTypeOf); // the extended callback
begin
typeof = 1;
if component.Syncro(???) then begin // <-------- how to ???
// do stuff
end;
end;

// the main form
// the real callback function
procedure TFormMain.Feddback(aTypeOf : Integer; param1: Integer);
begin
if aTypeOf = 0 then begin
label1.caption = IntToStr(param1);
end else begin
label2.caption = IntToStr(param1);
end;
end;
// usage of datamodule
procedure TFormMain.btn1Click(Sender: TObject);
begin
dataModule.UseMethod(Feddback);
end;

有任何想法吗?还有其他方法可以做到这一点吗? (我在 FMX 环境中也需要这个)

很多东西

拉兹万

最佳答案

如果您自己编写了组件,那么最简单的做法是更改 TFeedbackProcedure 的类型声明。这样它也接受匿名方法(以及对象方法):

TFeedBackProcedure = reference to procedure(param1 : Integer);

这使您可以将扩展方法包装到位并像这样调用它:
procedure UseMethod(feedbackProcedure : TFeedBackProcedureByTypeOf);
var
_typeOf : integer;
begin
_typeOf = 1;
component.Syncro(procedure(AParam : integer)
begin
feedbackProcedure(_typeOf, AParam);
end);
end;

我在这里简单地展示了调用该方法,因为您的示例写入 .Synchro就好像它是一个返回 bool 值的函数,而事实上,您已经将它声明为一个简单的过程。

作为替代方案,如果您无法更改方法签名或向现有类添加包装器,则始终可以编写包装器类来完成这项工作。我在这里展示了一个专用的包装类,但是您可以轻松地将这些字段和方法添加到任何合适的类中,以将功能包装到具有正确签名的对象方法中。
  TCallbackContainer = class
private
FParam : integer;
FFeedbackProcByTypeOf : TFeedBackProcedureByTypeOf;
public
constructor Create(AProcByTypeOf : TFeedBackProcedureByTypeOf);
procedure WrapCallback(AParam:integer);
property IntParam : integer read FParam write FParam;
end;

实现:
  constructor TCallbackContainer.Create(AProcByTypeOf : TFeedBackProcedureByTypeOf);
begin
FFeedbackProcByTypeOf := AProcByTypeOf;
end;

procedure TCallbackContainer.WrapCallback(AParam: Integer);
begin
FFeedbackProcByTypeOf(FParam, AParam);
end;

然后你可以这样称呼:
procedure UseMethod(feedbackProcedure : TFeedBackProcedureByTypeOf);
var
LCallbackContainer : TCallbackContainer;
begin
LCallBackContainer := TCallbackContainer.Create(feedbackProcedure);
try
LCallBackContainer.IntParam := 1;
component.Syncro(LCallbackContainer.WrapCallback);
finally
LCallBackContainer.Free;
end;
{ Or, make it FCallBackContainer and manage lifetime somehow...}
end;

与引用计数的匿名方法不同,您必须管理 LCallbackContainer对象生命周期在这里不知何故。我已将其显示为本地,如果 .Synchro 则很好实际上是完全同步的,您可以在回调容器返回时释放它。如果 。 Synchro然而,它实际上是一个异步方法,并在其工作完成之前返回,那么您需要一些方法来管理回调包装器的生命周期。

您还应该避免命名变量 TypeOf因为这将隐藏 the standard method用那个名字。 System.TypeOf已弃用,但避免这样的命名冲突仍然是一种好习惯。

关于Delphi 叠瓦式回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40378312/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com