インターフェイスの自動参照カウントを使用することの短所に関する StackOverflow の多くの投稿を読んだ後、各インターフェイスのインスタンス化を手動で参照カウントしようとし始めました。
午後いっぱい試した後、あきらめました!
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.