var
intf: ITest;
...
intf:= CreateComObject(CLASS_TEST) as ITest;
...
//here comes some stuff
...
我必须做些什么来破坏它以释放记忆 . 或不?
4 回答
2
所有COM接口必须实现 IUnknown :
IUnknown = interface
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;
4 回答
所有COM接口必须实现
IUnknown
:IUnknown
提供两种服务 . 首先,QueryInterface
允许客户端获取对象可能实现的其他接口 . 第二项服务是终身管理 .每次引用COM对象时,您都有责任调用
_AddRef
. 每次放弃对COM对象的引用时,您都签约调用_Release
._AddRef
和_Release
的规范实现是为了实现对象来维护引用计数变量,该变量在获取和释放引用时递增和递减 . 如果对_Release
的调用将此引用计数设置为0,则该对象将自行销毁 .Delphi的接口实现代表您管理对
_AddRef
和_Release
的调用 . 分配给接口变量时,编译器会发出以下代码:在变量先前引用的接口上调用
_Release
,如果它之前确实引用了某个东西 .在变量现在引用的接口上调用
_AddRef
.只要变量离开作用域,编译器也会安排调用
_Release
.这意味着您不需要采取任何特殊操作来确保您的COM对象将被销毁 . 当对象的最后一次引用离开范围时,它们自然会被销毁 .
但是,如果您希望提前销毁对象,则只需将
nil
分配给保存接口的变量 . 请注意,这当然是假设没有其他引用持有该接口 .你应该更好地释放内存
当你不再需要它时 . 如果
intf
被定义为fIntf
,则更好地使用try...finally intf := nil;
块或Destroy
覆盖方法,即作为类属性 .如果在堆栈上定义
intf
,它将在方法结束时自动释放 . 编译器生成一个隐藏的try...finally intf := nil; end
块以释放intf
实例 .COM对象是引用计数的,当引用计数达到零时它们会自动销毁 . 只要您的代码添加对对象的引用或将其删除,编译器就会自动添加对
_AddRef
和_Release
接口方法的调用 . 将引用COM对象的变量设置为nil
将调用_Release
(递减引用计数),如果引用计数达到零,则对象也将被释放(如果引用计数不为零则不会) . 当变量超出范围(即局部变量,当过程退出时)时,如果变量引用COM对象(或任何引用计数的Delphi接口),编译器也将调用_Release
.该对象自动释放 . 但是,如果您明确要释放
intf
变量所持有的引用,则可以将其设置为nil .