Delphi接口自动引用计数:对象内存管理相关疑问
问题描述
给定以下Pascal代码:
接口与实现类型
IMyBuilderIntf = interface function Build(): String; end; //... TMyConcreteType = class(TInterfacedObject, IMyBuilderIntf) //... function Build(): String; end;
接收接口的函数
function MyFunctionUsingInterface(AParam: IMyBuilderIntf): Boolean; begin //... AParam.Build(); //... end;
客户端调用代码
function EntryPoint(): Integer; var concreteBldr: TMyConcreteType; begin // 调用TMyConcreteType中声明的特定方法 MyFunctionUsingInterface(concreteBldr); // <<<<<<<<< end;
请问:
- 存储在
concreteBldr中的对象内存会被自动管理吗? - 是否所有通过接口访问的对象都会被自动管理?
- 该自动管理行为是否依赖对象之前声明的类型(具体或抽象)?
解答
1. concreteBldr中的对象内存不会被自动管理
concreteBldr是具体类类型变量,并非接口类型。当你把它传递给MyFunctionUsingInterface时,会隐式生成一个临时接口引用,但这个临时引用在函数执行结束后就会被释放。而原始的concreteBldr作为类类型变量,不会触发Delphi的引用计数机制——Delphi的自动内存管理仅对接口类型变量生效,类类型变量必须手动调用Free释放内存,否则会造成内存泄漏。
2. 并非所有通过接口访问的对象都会被自动管理
只有满足两个条件才会触发自动内存管理:一是对象的类继承自TInterfacedObject(或其他正确实现IInterface引用计数逻辑的类),二是通过接口类型变量持有对象引用。如果对象的类没有实现_AddRef、_Release这类引用计数方法,哪怕通过接口访问,也不会自动管理内存。
3. 自动管理行为不依赖对象声明的类型(具体/抽象)
该行为只取决于两个核心条件:
- 对象的类是否正确实现了
IInterface的引用计数方法(通常继承TInterfacedObject即可自带实现); - 是否通过接口类型变量持有对象的引用。
无论对象是具体类还是抽象类,只要满足上述两个条件,就能触发自动内存管理;反之,哪怕是具体类,用类类型变量持有也不会自动释放。
内容的提问来源于stack exchange,提问作者Arthur Araujo
相关产品推荐
相关产品推荐

