7

我有一个具有 TComponent 变量的单元,我在单元初始化时创建此组件,如下所示:

var
  XComp: TComponent;
.
.
.
.

initialization
begin
  XCom := TComponent.Create(Application);
end;

在我关闭 Delphi 时安装该单元后,它给我一个访问冲突错误消息 (EAccessViolation)

但是当我将我的创建者更改为如下

initialization
begin
  XCom := TComponent.Create(nil);
end;

一切顺利...我想知道区别?什么是更好的?

注意:错误仅在关闭 delphi 时出现(意味着在设计时)。

谢谢。

4

2 回答 2

13

当你使用

XCom := TComponent.Create(Application);

您让应用程序成为 XCom 的所有者。当应用程序终止时,它将负责销毁 XCom,因为它是所有者。

当你这样做

XCom := TComponent.Create(nil);

没有人是 XCom 的所有者,您必须在应用程序终止时自行释放它。

您可能遇到了异常,因为您手动释放了 XCom,然后应用程序也尝试释放 XCom。

于 2012-08-04T11:15:14.090 回答
2

基本上两者都是允许的,即使你有这样的代码也不应该产生 AV:

MyComp := TMyComp.Create(Application);
try
  {...}
finally
  MyComp.Free;
end;

这是因为正确编码的组件在被销毁时会从其所有者的组件列表中删除。

我认为这里的问题可能是该组件已经被应用程序对象释放,后来一些代码尝试访问它。也许您的代码中有一个 finalize 部分,是吗?或者你可能有混合的对象和接口,引用计数让你受益。

要调试您的问题,您可以通过将包的“主机应用程序”设置为 Delphi (C:\Program Files\\BDS\\Bin\bds.exe) 在调试器中运行 IDE。并在组件的析构函数中设置断点。这样你就会知道它在哪里被释放以及 AV 发生在哪里。

于 2012-08-05T10:05:27.973 回答