Delphi   发布时间:2022-04-11  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了delphi – 没有引用计数的接口大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在StackOverflow上阅读了很多关于使用Interfaces自动引用计数的缺点后,我开始尝试手动引用计数每个接口实例化.

在尝试了整整一个下午后,我放弃了!

当我调用FreeAndNil(p)时,为什么会出现访问冲突?

以下是我的简单单元的完整列表.

unit fMainForm;

interface

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

type
  TForm4 = class(TForm)
    btn1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  end;

type
  IPersona = interface(IInterfacE)
  ['{44483AA7-2A22-41E6-BA98-F3380184ACD7}']
    function GetNome: String;
    procedure SetNome(const Value: String);
    property Nome: String read GetNome write SetNome;
  end;

type
  TPersona = class(TObject,IPersona)
  Strict private
    FNome: String;
    function GetNome: String;
    procedure SetNome(const Value: String);
  protected
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
  public
    constructor Create(const ANome: String);
    destructor Destroy; override;
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

procedure TForm4.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;
end;

procedure TForm4.btn1Click(Sender: TObject);
var
  p: IPersona;
begin
  p := TPersona.Create('Fabio');
  try
    Showmessage(p.NomE);
  finally
    FreeAndNil(p);
  end;
end;

constructor TPersona.Create(const ANome: String);
begin
  inherited Create;
  FNome := ANome;
end;

destructor TPersona.Destroy;
begin
  inherited Destroy;
end;

function TPersona._AddRef: Integer;
begin
  Result := -1
end;

function TPersona._Release: Integer;
begin
  Result := -1
end;

function TPersona.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
  if GeTinterface(IID,Obj) then
    Result := S_OK
  else
    Result := E_NOINTERFACE;
end;

function TPersona.GetNome: String;
begin
  Result := FNome;
end;

procedure TPersona.SetNome(const Value: String);
begin
  FNome := Value;
end;

end.

解决方法

发生访问冲突是因为FreeAndNil接收到一个非类型化的var参数,该参数应该是一个对象引用.您正在传递不符合要求的接口引用.不幸的是,你只能在运行时找到它.在我看来,这是反对使用FreeAndNil的最强点.

您的引用计数通过接口引用计数机制禁用生命周期管理.为了销毁一个对象,你需要调用它的析构函数.为了做到这一点,你必须有权访问析构函数.您的接口不公开析构函数(它不应该).因此,我们可以推断出,为了销毁对象,您需要有一个对象引用.

以下是一些选项:

var
  obj: TPersona;
  intf: IPersona;
....
obj := TPersona.Create('Fabio');
try
  intf := obj;
  //do stuff with intf
finally
  obj.Free;
  // or FreeAndNil(obj) if you prefer
end;

或者你可以这样做

var
  intf: IPersona;
....
intf := TPersona.Create('Fabio');
try
  //do stuff with intf
finally
  (intf as TObject).Free;
end;

大佬总结

以上是大佬教程为你收集整理的delphi – 没有引用计数的接口全部内容,希望文章能够帮你解决delphi – 没有引用计数的接口所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。