我可以使用.Create(Nil)代替.Create(应用程序)

use*_*094 7 delphi delphi-xe2 tcomponent

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

var
  XComp: TComponent;
.
.
.
.

initialization
begin
  XCom := TComponent.Create(Application);
end;
Run Code Online (Sandbox Code Playgroud)

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

但是当我改变我的创造者时如下

initialization
begin
  XCom := TComponent.Create(nil);
end;
Run Code Online (Sandbox Code Playgroud)

一切都很顺利...我想知道区别吗?什么更好?

注意:只有在关闭delphi时才会出现错误(在设计时意味着).

谢谢.

Bir*_*ger 13

当你使用

XCom := TComponent.Create(Application);
Run Code Online (Sandbox Code Playgroud)

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

当你这样做

XCom := TComponent.Create(nil);
Run Code Online (Sandbox Code Playgroud)

没有人是XCom的所有者,你必须在应用程序终止时自己释放它.

您可能有异常,因为您手动释放了XCom,然后Application也试图释放XCom.

  • +1.作为一般指南:使用`时,你会被自己释放的对象,而`Application`如果你不是,你想它清理,为您或如果有一个机会,你将无法释放它nil`你自己. (5认同)

dum*_*uch 2

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

MyComp := TMyComp.Create(Application);
try
  {...}
finally
  MyComp.Free;
end;
Run Code Online (Sandbox Code Playgroud)

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

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

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