Habe gerade etwas fest gestellt, von dem ich bisher erwartet hatte, dass es funktioniert. Ich arbeite sehr intensiv mit Interfaces und schaue auch immer, dass ich Objekt- und Interfacereferenzen nicht vermische.
Das heißt, Variable vom Interface-Typ definierten und das Objekt mittels Create der Variable zuweisen. Wenn die Interface-Variable aus dem Scope fällt, wird das Objekt dahinter auch immer schön frei gegeben. So soll das sein!
Jetzt hätte ich erwartet, wenn eine Methode eine Interface-Variable übernimmt, und ich beim Aufruf direkt die neu erstelle Objekt-Referenz übergebe, dass der RefCount und die Freigabe korrekt funktionieren. Dem ist anscheinend nicht so. Im Folgenden mal ein Beispiel-Code. Habe an der entsprechenden Stelle einen Kommentar eingefügt...
Delphi-Quellcode:
type
IMyInterface = interface(IInterface)
['{475ACE39-ECC7-467D-A325-35B2DF22203A}']
procedure DoSomething;
end;
TMyInterface = class(TInterfacedObject, IMyInterface)
private
procedure DoSomething;
public
destructor Destroy; override;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
procedure Machwas(const AValue: IMyInterface);
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
destructor TMyInterface.Destroy;
begin
ShowMessage('Free!');
end;
procedure TMyInterface.DoSomething;
begin
//...
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Value: IMyInterface;
begin
//Wenn der Aufruf auf diese Weise erfolgt, wird das Objekt NICHT frei gegeben.
Machwas(TMyInterface.Create);
//So wird das Objekt korrekt frei gegeben
Machwas(TMyInterface.Create as IMyInterface);
//so wird das Objekt auch korrekt frei geben
Value := TMyInterface.Create;
Machwas(Value);
end;
procedure TForm1.Machwas(const AValue: IMyInterface);
begin
AValue.DoSomething;
end;
Ist das logisch? Hätte ich bisher anders erwartet... da mir aber der Speicher voll lief, wurde ich eines besseren belehrt.