Dopo aver letto più post su StackOverflow circa gli svantaggi dell'utilizzo del conteggio di riferimento automatico per le interfacce, ho iniziato a provare a fare riferimento manualmente al conteggio di ciascuna istanza di interfaccia.Interfacce senza conteggio di riferimento
Dopo aver provato per un intero pomeriggio mi arrendo!
Perché ottengo la violazione di accesso quando chiamo FreeAndNil (p)?
Quello che segue è un elenco completo della mia unità semplice.
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.
+1 non avevo idea che si potrebbe semplicemente typecast un'interfaccia a un TObject. * (non l'ho provato, ma provenendo da te, presumo sia corretto) * –
@Lieven Solo in alcune delle più recenti versioni di Delphi è supportato. O 2009 o 2010. Non riesco a ricordare esattamente quando. –
David, grazie! le tue soluzioni (entrambe) funzionano come un incantesimo (come per ogni risposta che pubblichi su StackOverflow ;-)) GRANDI !!!! –