加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 释放内部接口问题的接口

发布时间:2020-12-15 09:28:26 所属栏目:大数据 来源:网络整理
导读:我这里有一个代码: unit Unit1;interfaceuses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls;type IInnerTest = interface (IInterface) procedure DoSth; end; TRekScannerData = record Source: Integer; Device
我这里有一个代码:

unit Unit1;

interface

uses
  Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls;

type
  IInnerTest = interface (IInterface)
    procedure DoSth;
  end;

  TRekScannerData = record
    Source: Integer;
    Device: IInnerTest;
  end;

  ITest = interface (IInterface)
    procedure DoSth;
  end;

  ATest = class(TInterfacedObject,ITest)
  private
    FInner: Array of TRekScannerData;
  public
    procedure DoSth;
    constructor Create();
    Destructor Destroy();override;
  end;

  AInnerTest = class (TInterfacedObject,IInnerTest)
  private
    FMainInt: ITest;
  public
    constructor Create(MainInt: ITest);
    procedure DoSth;
    Destructor Destroy();override;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  test: ITest;

implementation

{$R *.dfm}

{ ATest }

constructor ATest.Create;
begin
  SetLength(FInner,1);
  FInner[0].Device := AInnerTest.Create(self);
  //<----- Here is the reason. Passing main interface to the inner interface.
end;

destructor ATest.Destroy;
begin
  beep;
  inherited;
end;

procedure ATest.DoSth;
begin
  //
end;

{ AInnerTest }

constructor AInnerTest.Create(MainInt: ITest);
begin
  FMainInt := MainInt;
end;

destructor AInnerTest.Destroy;
begin
  beep;
  inherited;
end;

procedure AInnerTest.DoSth;
begin
  //
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  test := ATest.Create;
  test.DoSth;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  test := nil;
end;

end.

问题是当测试分配给nil时不会调用Destroy;

我想通过一个声明释放所有内部接口……
可能吗?或者我是否需要在零之前使用其他方法销毁所有内部结构?

编辑

类结构如下:

Var x = ITest(ATest class) has ->
  Inner Interface: IInnerTest(AInnerTest class) which has reference to:
    ITest(ATest class)

Nil’ing x不释放所有结构……

解决方法

你有一个循环参考.您对IInnerTest的实现包含对ITest的引用.您对ITest的实现包含对IInnerTest的引用.此循环引用意味着接口引用计数永远不会为零.

这个问题的正常解决方案是使用弱引用.一些有用的链接:

> “Weak reference”: down to earth explanation needed
> http://www.finalbuilder.com/Resources/Blogs/PostId/410/WeakRefence-in-Delphi-solving-circular-interfac.aspx
> http://delphisorcery.blogspot.co.uk/2012/06/weak-interface-references.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读