Hallo,
Zitat von
negaH:
Nein, die Referenzzählung arbeitet einwandfrei, du machst einfach einen logischen Denkfehler.
Ich hab' da keinen Denkfehler, keine Angst. Erklärung folgt.
Zitat von
negaH:
Bei Test1 existiert defakto KEIN lokaler Gültigkeitsbereich für ein Interface. Ergo wenn man ein Object direkt einer Funktion übergibt die ein Interface erwartet und dieses NICHT als const deklariert hat, so wird das Objekt zerstört. Das ist auch logisch, denn betrachte mal den Fall das man TuWas() aufruft mit einem gerade frisch allozierten Interface das später im Program NICHT weiter benutzt wird. Würde der Compiler anderes arbeiten würde dieses allozierte Interface als Speicherleiche übrig bleiben.
Du benutzt aber ein anderes Beispiel als wir hier diskutieren. Bei uns sieht das so aus:
Delphi-Quellcode:
procedure Test1;
begin
FMyObject := TMyObject.Create;
TuWas(FMyObject);
TuWasAnderes(FMyObjekt);
end;
Hier knallts, weil eben der erste Aufruf den Referenzzähler erhöht und wieder vermindert, wodurch das Objekt freigegeben wird. Bei TuWasAnderes ist also das Objekt schon zerstört.
Natürlich ist dieses Verhalten korrekt (was die Referenzzählung von Interfaces angeht), aber, und das ist der Punkt, unerwartet. Wer noch nicht so viel Ahnung von Interfaces hat, würde annehmen, dass FMyObjekt ja auch eine Refernez ist, aber auf das Objekt. Nur gibt's bei Objekten keinen Referenzzähler
. Darum geht's mir, ich will nur auf diese Stolperfalle hinweisen. Und hier könnte der Delphi-Compiler tatsächlich erkennen, dass ich das Objekt
nicht freigeben will und noch einen Referenzblock rumbasteln. Da Delphi das nicht macht, kann man es selbst machen.
Zitat von
negaH:
Fazit: wenn man mit Objekten und Interfaces arbeiten möchte dann sollte man immer mit Hilfe einer lokalen Interfacevariablen, in der man das Object speichert, arbeiten.
Was übrigens das Gleiche macht, wie ich, nur implizit statt explizit.
Aber wie wäre es eigentlich damit, und hier sind wir wieder beim Thema des Threads, wenn das Objekt zwei Interfaces implementiert, wobei nur das eine an das Plugin weitergegeben wird, während das andere im Hauptprogramm verwendet wird? So bräuchts man sich nicht mit diesem Problem rumschlagen.
Gruß
xaromz