【问题标题】:How to check if a instance was already freed in this case?在这种情况下如何检查实例是否已被释放?
【发布时间】:2015-03-05 15:23:03
【问题描述】:

在我们的应用程序框架中,我们有某种实例处理程序类,在恢复时它负责捕获由我们的其他控制器/组件/表单/等创建的实例。

声明如下:

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;

以及实现:

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;

接下来发生的事情是,当TInstanceHandler 最终确定时,它将尝试再次释放委托的实例,这将导致错误。 我知道为什么Assigned 在这种情况下失败的季节,据我所知,我不能使用FreeAndNil

所以问题是:如何正确检查引用是否已被释放?

【问题讨论】:

  • 你为什么不使用 TObjectList
  • @whosrdaddy TObjectList 会导致同样的错误,这就是为什么我尝试更改为 TList 以便我可以检测到应该免费的内容
  • 我明白了,无论如何正如大卫所说,在这种情况下没有出路。
  • if(Assigned(AInstance)) then AInstance.Free() 应该是 AInstance.Free() 并且您的 Delegate 方法旨在返回一个值而不是。

标签: delphi delphi-xe2


【解决方案1】:

如何正确检查引用是否已被释放?

你不能。

【讨论】:

  • 就这么简单?没有解决方法什么的?我在这里尝试做的是在for 中使用try except 以保持执行即使在free 引发错误之后也能继续运行,但令我惊讶的是,我在应用程序EInvalidPointer 的末尾出现了泄漏跨度>
  • 是的,就这么简单。该对象可以被释放,现在任何取消引用您对它的引用的尝试,这只是一个指针,都是错误的。同时,内存管理器可能已经分配了该类型的另一个对象,以重新使用该地址。你怎么能把它和你误删的旧的区分开来。这个故事的寓意是,程序员必须遵守规则。有些规则无法由框架强制执行。自动引用计数可以处理所有这些问题,但您可能无法使用。
  • 我明白了,我同意这也不是框架的责任,发生的是有时 ppl 是一种痛苦,他们往往不负责任,这就是我试图在框架上实现它的原因。反正thx
  • 不管怎样,你的问题的答案和我说的完全一样。但很可能有其他方法来设计解决潜在问题的框架。
  • 既然你知道这门课的目的,请指出这些替代方案是什么,以便我可以实现?
猜你喜欢
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2014-05-10
相关资源
最近更新 更多