我有一个具有TComponent变量的单元,我在单元初始化时创建这个组件,如下所示:
var
XComp: TComponent;
.
.
.
.
initialization
begin
XCom := TComponent.Create(Application);
end;
在我关闭Delphi后安装单元后,它给我一个访问冲突错误消息(EAccessViolation)
但当我将我的创作者改为
时initialization
begin
XCom := TComponent.Create(nil);
end;
一切都很顺利......我想知道区别吗?什么更好?
注意:只有在关闭delphi时才会出现错误(意味着在设计时)。
感谢。
答案 0 :(得分:13)
使用时
XCom := TComponent.Create(Application);
您将应用程序作为XCom的所有者。当应用程序终止时,它将负责销毁XCom,因为它是所有者。
当你这样做时
XCom := TComponent.Create(nil);
没有人是XCom的所有者,您必须在应用程序终止时自行释放它。
你可能得到了异常,因为你手动释放了XCom,然后Application也试图释放XCom。
答案 1 :(得分:2)
基本上两者都是允许的,即使你有这样的代码也不应该导致AV:
MyComp := TMyComp.Create(Application);
try
{...}
finally
MyComp.Free;
end;
这是因为正确编码的组件在被销毁时会从其所有者的组件列表中删除。
我认为这里的问题可能是组件已被应用程序对象释放,稍后某些代码会尝试访问它。也许你的代码中有一个finalize部分,它可以吗?或者你可能有混合对象和接口,引用计数就可以了。
要调试您的问题,可以通过将软件包的“主机应用程序”设置为Delphi(C:\ Program Files \\ BDS \\ Bin \ bds.exe)来在调试器中运行IDE。 并在组件的析构函数中设置断点。这样你就可以找到它被释放的位置以及AV发生的位置。