gpt4 book ai didi

delphi - 用接口(interface)在 Delphi 中实现观察者模式

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

首先,大家好,感谢您的帮助。

我正在尝试使用接口(interface)在 Delphi 中实现观察者模式,因此对象可以同时是主题和观察者。

我有一个实现 ISubject 的类,方法如下:

procedure TSomeClass.Attach(const observer: IObserver);
var
I: Integer;
begin
if Fobservers = nil then
begin
Fobservers := TInterfaceList.Create;
end;
if Fobservers.IndexOf(Observer) < 0 then
Fobservers.Add(Observer);
end;

我在 http://blogs.teamb.com/joannacarter/2004/06/30/690 上按照 Joanna Carter 的示例进行操作。 .

在应用程序中,我实例化了一个实现 IObserver 的对象,并将它附加到 TSomeClass 对象(它也实现了 ISubject)。

然后我从 TSomeClass 对象调用 Notify 方法,它可以正常工作。当我尝试 FreeAndNil 我的 Observer 对象时出现我的问题,因为我得到一个无效的指针操作,即使我在参数中使用“const”并且当我在 Debug模式下到达 FreeAndNil 行时,对象被正确分配,所有属性都已设置,并且在通知内更改了随机属性。

我注意到当我调用此行时,我无法释放我的对象了:
Fobservers.Add(Observer);

如果我评论这一行,那么我可以释放我的对象。应用程序内部的代码如下所示:
procedure TfrmAlisson.Button2Click(Sender: TObject);
var
locSomeClass: TSomeClass;
locObserver: TSomeObserverClass;
I: Integer;
begin
locObserver:= TSomeObserverClass.create(394693);
try
locSomeClass:= TSomeClass.create(263151);
try
locSomeClass.Attach(locObserver);
locSomeClass.NotifyObservers;
finally
FreeAndNil(locSomeClass);
end;
ShowMessage(IntToStr(locObserver.SomeProperty)); // This property is changed inside the notify
finally
locObserver.Free; // error
end;
end;

我想知道为什么将 IObserver 添加到 TInterfaceList 会导致这种情况(我使用的是 Delphi 2009)。

最佳答案

您的 TSomeObserverClass最有可能继承自 TInterfacedObject .

当你通过 Attach它被传递为 IObserver这就是引用计数开始的地方。当它被添加到 Fobservers 时,RefCount 变为 1。当你摧毁 locSomeClass以及Fobservers列出它再次被删除,导致 RefCount 下降到 0。然后 IObserver 后面的实例接口(interface)引用正在被破坏。

为了显示这里的问题是重现它的最少代码:

var
obj: TInterfacedObject;
list: TInterfaceList;
begin
o := TInterfacedObject.Create;
try
list := TInterfaceList.Create;
list.Add(o);
list.Free;
finally
FreeAndNil(o);
end;
end;

如果执行此操作,您会在 FreeAndNil 中看到 EInvalidError,这是因为实例已被 TInterfacedObject 中实现的自动引用计数破坏而导致。 .

正如已经评论过的,您不应该混合对象和接口(interface)引用或从不实现自动引用计数的类继承。

关于delphi - 用接口(interface)在 Delphi 中实现观察者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18729324/

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