Der Aufruf von ._AddRef() und ._Release() ist eine sehr schlechte Idee und sollte eigentlich niemals notwendig sein.
Bei der Benutzung von Interfaces in Delphi ist ein Punkt ganz wichtig: Alle Zugriffe auf ein Objekt sollten immer über das Interface erfolgen. Eine manuelle Freigabe der Objekte hinter dem Interface oder des Interfaces selber ist niemals notwendig.
Werden Interfaces als Paramater benutzt so sollte man diese als CONST deklarieren. Dies ist aber keine zwingende Notwendigkeit wenn man zb. die Variable selber in der Funktion noch weiter benutzen möchte. Der Unterschied zwischen CONST und nicht CONST ist nachfolgender:
Delphi-Quellcode:
procedure XYZ(MyIntf: IInterface);
// try
// MyIntf._AddRef; <- unsichtbarer Code durch den Compiler erzeugt
begin
MyIntf :=
nil;
// zulässige Anweisung um das Interface "freizugebenen" innerhalb der lokalen Gültigkeit
// MyIntf._Release; <- unsichtbarer Code durch Compiler
MyIntf := ABC;
// zulässig
// MyInt._Release; <- usichtbarer Code
// ABC._AddRef
// MyIntf := ABC;
MyIntf._Release;
// TÖDLICH und absolut FALSCH, Variable MyIntf ist weiter <> nil und erzeugt AV im
// letzten unsichtbaren try finally Block unten
end;
// finally <- unsichtbarer
// MyIntf._Release;
// end;
procedure XYZ(
const MyIntf: IInterface);
// <- KEIN try finally durch compiler
begin
MyIntf :=
nil;
// <- unzulässig da MyIntf ein Konstante
MyIntf := ABC;
// <- unzulässig
MyIntf._Release;
// eventuell TÖDLICH da das Interface danach einen Reference Counter von X -1 hat. Unter
// Umständen wird das Objekt hinter dem Interface freigegeben
// Es kann also auch erwünscht sein
end;
Man sieht das bei dem Aufruf mit CONST
1.) die Anwendung schneller wird weil der Compiler auf ein try finally Block verzeichten kann
2.) der Source SICHERER wird da man nicht unbeabsichtig wie im ersten Beispiel die Paramatervariable modifizieren kann
Bei der Erzeugung von Interface geht man immer so vor
Delphi-Quellcode:
var
MyIntf: IInterface;
// try <- unsichtbarer Code des Compilers
// Pointer(MyIntf) := nil;
begin
MyIntf := TObjectClass.Create;
MyIntf.Methode1();
end;
// finally <- unsichtbarer Code
// MyIntf._Release;
// end;
Man sieht auch hier wieder das ein Aufruf von ._AddRef() und ._Release() wiederum TÖDLICHE Konsequenzen haben wird.
Gruß Hagen