Delphi 在这种情况下,如何检查实例是否已被释放?
在我们的应用程序框架中,我们有一些实例处理程序类,它负责捕获其他控制器/组件/表单等创建的实例 声明如下:Delphi 在这种情况下,如何检查实例是否已被释放?,delphi,delphi-xe2,Delphi,Delphi Xe2,在我们的应用程序框架中,我们有一些实例处理程序类,它负责捕获其他控制器/组件/表单等创建的实例 声明如下: TInstanceHandler = class(TFrameworkClass) strict private FInstances : TList<TObject>; procedure FreeInstances(); protected procedure Initialize(); override; procedure Finalize(); ove
TInstanceHandler = class(TFrameworkClass)
strict private
FInstances : TList<TObject>;
procedure FreeInstances();
protected
procedure Initialize(); override;
procedure Finalize(); override;
public
function Delegate<T : class>(const AInstance : T) : T;
end;
接下来发生的是,当TInstanceHandler
完成时,它将再次尝试释放委派的实例,这将导致错误。
我知道在这种情况下,Assigned
失败的原因,就我所知,我不能使用FreeAndNil
所以问题是:如何正确地检查引用是否已被释放
如何正确检查引用是否已被释放
你不能
如何正确检查引用是否已被释放
你不能。这么简单吗?没有解决办法还是什么?我在这里试图做的是使用
try
除了for
中的来保持执行,即使free
引发了一个错误,但令我惊讶的是,我在应用程序EInvalidPointer
的末尾发现了一个漏洞,就是这么简单。该对象可以被释放,现在任何试图取消对它的引用(只是一个指针)的尝试都是错误的。同时,内存管理器可能已经使用该地址分配了该类型的另一个对象。你怎么能把它和你误删除的旧的区别开来呢。这个故事的寓意是,程序员必须遵守规则。有些规则是框架无法强制执行的。自动引用计数可以解决所有这些问题,但您可能无法使用。我明白了,我同意这也不是框架的责任,发生的事情是,有时ppl是一种痛苦,他们往往不负责任,这就是为什么我试图在框架上实现这一点。无论如何,Thxanway,你的问题的答案和我说的一模一样。但是很可能有其他设计框架的方法来解决潜在的问题。既然您知道这个类的目的,那么请注意指出这些方法是什么,这样我就可以实现它了?就这么简单吗?没有解决办法还是什么?我在这里试图做的是使用try
除了for
中的来保持执行,即使free
引发了一个错误,但令我惊讶的是,我在应用程序EInvalidPointer
的末尾发现了一个漏洞,就是这么简单。该对象可以被释放,现在任何试图取消对它的引用(只是一个指针)的尝试都是错误的。同时,内存管理器可能已经使用该地址分配了该类型的另一个对象。你怎么能把它和你误删除的旧的区别开来呢。这个故事的寓意是,程序员必须遵守规则。有些规则是框架无法强制执行的。自动引用计数可以解决所有这些问题,但您可能无法使用。我明白了,我同意这也不是框架的责任,发生的事情是,有时ppl是一种痛苦,他们往往不负责任,这就是为什么我试图在框架上实现这一点。无论如何,Thxanway,你的问题的答案和我说的一模一样。但是很可能有其他设计框架的方法来解决潜在的问题。既然您知道这个类的用途,请注意指出这些方法是什么,以便我可以实现它?为什么不使用TObjectList?@whosrdaddyTObjectList
将导致相同的错误,这就是为什么我试图切换到TList
,这样我就可以检测出什么应该是免费的。我知道,无论如何,正如David所说,在这种情况下没有出路。如果(分配(AInstance)),那么AInstance.Free()应该是AInstance.Free()
而您的委托方法是要返回一个值而不是。您为什么不使用TObjectList可能存在重复?@whosrdaddyTObjectList
将导致相同的错误,这就是为什么我试图更改为TList
,这样我就可以检测到应该免费的内容,正如David所说的,在这种情况下没有出路。if(Assigned(AInstance)),那么AInstance.Free()
应该是AInstance.Free()
,并且您的委托方法将返回一个值,并且不可能重复
procedure TInstanceHandler.FreeInstances();
var AInstance : TObject;
begin
for AInstance in FInstances do
if(Assigned(AInstance)) then AInstance.Free();
FInstances.Free();
end;
procedure TInstanceHandler.Initialize();
begin
inherited;
FInstances := TList<TObject>.Create();
end;
procedure TInstanceHandler.Finalize();
begin
FreeInstances();
inherited;
end;
function TInstanceHandler.Delegate<T>(const AInstance : T) : T;
begin
FInstances.Add(AInstance);
end;
with InstanceHandler.Delegate(TStringList.Create()) do
try
//...
finally
Free();
end;