如何在TInterfacedObject中释放TObject成员 [英] How to free a TObject member in a TInterfacedObject

查看:175
本文介绍了如何在TInterfacedObject中释放TObject成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道接口对象是引用计数,因此不需要手动释放它。但是,如果它具有TObject继承的成员,是否应该在析构函数中手动释放该成员?

I know an interfaced object is reference counted, so need not to manually free it. But if it has a TObject inherited member, should I manually free this member in the destructor?

考虑以下代码:

program Project2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes;

type
  ITestInterface = interface(IInvokable)
    ['{A7BDD122-7DC6-4F23-93A2-B686571AB2C8}']
    procedure TestMethod;
  end;

  TTestObj = class(TInterfacedObject, ITestInterface)
    constructor Create;
    destructor Destroy; override;
  private
    FData: TStrings;
  public
    procedure TestMethod;
  end;

{ TTestObj }

constructor TTestObj.Create;
begin
  FData := TStringList.Create;
end;

destructor TTestObj.Destroy;
begin
  Writeln('Destroy'); // This line won't apear in the console ouput as the destructor won't be called.
  FData.Free;         // Who guarantees this member will be freed ?

  inherited;
end;

procedure TTestObj.TestMethod;
begin
  Writeln('TestMethod');
end;

{ Main }

procedure Main;
var
  TestObj: TTestObj;
begin
  TestObj := TTestObj.Create;
  TestObj.TestMethod;
  TestObj := nil;     // TestObj should be freed at this moment ?
end;

begin
  Writeln('Program start!');
  Main;
  Writeln('Program end.');
  Readln;
end.

程序输出:

Program start!
TestMethod
Program end.

这意味着未调用构造函数,而成员 FData 没有被释放?

It means the constructor was not been called, and the member FData was not been freed ?

我该怎么办?

推荐答案

TTestObj 中的代码很好。您必须像执行操作一样实现销毁 FData 的析构函数。

The code in TTestObj is fine. You must implement a destructor that destroys FData just as you have done.

问题出在其他地方。不会破坏接口对象,因为您永远不会触发任何引用计数。您需要通过接口变量来引用接口对象。替换

The problem lies elsewhere. The interfaced object is not being destroyed because you never trigger any reference counting. You need to refer to the interfaced object via an interface variable. Replace

TestObj: TTestObj

with

TestObj: ITestInterface

进行此更改后,接口引用代码将在您首次分配给 TestObj 变量时添加一个引用。

Once you make this change, the interface reference code will add a reference when you first assign to the TestObj variable.

顺便说一句,您不需要此行

As an aside, you don't need this line

TestObj := nil

TestObj 变量超出范围,引用计数将降至零,并且实现对象将被销毁。

When the TestObj variable goes out of scope, the reference count will drop to zero and the implementing object will be destroyed.

这篇关于如何在TInterfacedObject中释放TObject成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆