.net Delphi中COM对象的销毁
使用一些.net程序集,通过COM在delphi中调用它.net Delphi中COM对象的销毁,.net,delphi,com,.net,Delphi,Com,使用一些.net程序集,通过COM在delphi中调用它 var intf: ITest; ... intf:= CreateComObject(CLASS_TEST) as ITest; ... //here comes some stuff ... 我必须做些什么来破坏它以释放内存。是否?您最好用 intf := nil; 当你不再需要它的时候。最好使用try…finally intf:=nil
var
intf: ITest;
...
intf:= CreateComObject(CLASS_TEST) as ITest;
...
//here comes some stuff
...
我必须做些什么来破坏它以释放内存。是否?您最好用
intf := nil;
当你不再需要它的时候。最好使用try…finally intf:=nil如果intf
被定义为fIntf
,即作为类属性,则在Destroy
重写方法中
如果在堆栈上定义了intf
,我们将在方法末尾自动释放它。有一个隐藏的try…finally intf:=nil;结束编译器生成的
块以释放intf
实例。COM对象是引用计数的,当引用计数达到零时,它们会自动销毁。每当代码添加或删除对象引用时,编译器将自动添加对\u AddRef
和\u Release
接口方法的调用。将引用COM对象的变量设置为nil
将调用\u Release
(减少引用计数),如果引用计数为零,对象也将被释放(如果引用计数不为零,则不会释放)。当一个变量超出范围时(即当程序退出时为局部变量),如果该变量引用COM对象(或任何引用计数的Delphi接口),编译器也将调用\u Release
。该对象将自动释放。但是,如果明确希望释放intf
变量所持有的引用,可以将其设置为nil。所有COM接口都必须实现IUnknown
:
IUnknown = interface
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
IUnknown
提供两种服务。首先,QueryInterface
允许客户端获取对象可能实现的其他接口。第二种服务是生命周期管理
每次引用COM对象时,您都有责任调用\u AddRef
。每次放弃对COM对象的引用时,您都会被约定调用\u Release
\u AddRef
和\u Release
的规范实现是为了实现对象维护一个引用计数变量,该变量随着引用的获取和释放而递增和递减。如果对\u Release
的调用将此引用计数设置为0,则对象将销毁自身
接口的Delphi实现代表您管理对\u AddRef
和\u Release
的调用。当您分配给接口变量时,编译器将发出以下代码:
- 在变量先前引用的接口上调用
\u Release
,如果它确实先前引用了某些内容
- 在变量现在引用的接口上调用
\u AddRef
编译器还安排在变量离开作用域时调用\u Release
这意味着您不需要采取任何特殊措施来确保COM对象被销毁。当对象的最后一个引用离开作用域时,它们自然会被销毁
但是,如果确实希望提前销毁对象,则只需将nil
赋值给保存接口的变量即可。请注意,这当然是假定没有其他引用保存到该接口。我不熟悉delphi。你们所说的“在堆栈上定义”是什么意思,每个变量都在var部分定义,所以它们都在堆栈上?是的,它在堆栈中。因此,Delphi将在方法末尾发布此引用。如果intf存储在对象字段中,它将在对象销毁期间释放它。当我说“释放”时,我并不坚持引用的对象将被销毁,它的行为取决于它是如何设计的。p、 另外,当您想要更快地释放对象时,即如果您想要控制释放顺序,则需要为接口引用分配nil,-1,因为您“应该”释放内存不是真的。这是完全可选的。@Fred我写了“应该”,因为我发现,例如,一些Delphi编译器(不是旧的,我说的是Delphi 2010),即使它们“应该”并且有文档记录这样做。。。因此,我不能100%肯定情况会一直如此。我很高兴,如果你是如此自信,没有这样的问题发生过的接口。当然,我知道对象
已被弃用,接口也不是…;)