Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Object (Interface) <> nil (https://www.delphipraxis.net/193802-object-interface-nil.html)

EWeiss 11. Sep 2017 20:22

AW: Object (Interface) <> nil
 
Zitat:

Hast Du Deine Klasse von TInterfacedPersistent abgeleitet oder von TInterfacedObject?
Delphi-Quellcode:
TSkinPopUpMenu = class(TInterfacedPersistent, ISkinPopUpMenu)


Alle von TInterfacedPersistent.

Wird Dein Destructor des Objektes irgendwann aufgerufen?
Delphi-Quellcode:
destructor TSkinPopUpMenu.Destroy;
begin

  inherited;
end;
Nein niemals weil ich kein Free verwende.
Aber ich habe ihn addiert.

gruss

stahli 11. Sep 2017 20:25

AW: Object (Interface) <> nil
 
Ok, dann nur mal als Hinweis, falls Du das mal noch versuchen willst:

Du könntest von TInterfacedObject ableiten.
Dann wird das Objekt freigegeben, wenn die letzte Referenz darauf wegfällt.

Oder Du könntest es so lassen und selbst Free aufrufen.

Beides würde halt ein Speicherleck vermeiden.

EWeiss 11. Sep 2017 20:32

AW: Object (Interface) <> nil
 
Zitat:

Oder Du könntest es so lassen und selbst Free aufrufen.
Verstehe ich jetzt wirklich nicht.

http://www.delphipraxis.net/1380793-post8.html
Schon gar nicht das Objekt mit Free freigeben

sorry aber was ist denn nun richtig!
Habe jetzt alles geändert so das kein Free mehr aufgerufen wird.

ändere ich es nach TInterfacedObject dann wird Destroy aufgerufen ohne Free zu bemühen.

gruss

stahli 11. Sep 2017 21:17

AW: Object (Interface) <> nil
 
Du darfst das Objekt nicht freigeben, solange noch darauf oder auf seine Schnittstellen zugegriffen werden kann.

Also Du hast z.B.
Delphi-Quellcode:
myObj := TMyObj.Create;
myIntf1 := myObj;
myIntf2 := myObj;
Wenn Du TMyObj von TInterfacedObj ableitest, wird die automatische Referenzzählung unterstützt.
Wenn Du jetzt
Delphi-Quellcode:
myObj := nil;
myIntf1 := nil;
myIntf2 := nil;
aufrufst, wird automatisch TMyObj.Destroy aufgerufen.
Dazu ggf. der Haltepunkt dort, um das nachzuverfolgen.
Sofern Du aber irgendwo noch eine Referenz auf das Objekt hältst, ist der Referenzzähler noch größer 0 und das Objekt bleibt noch bestehen.

Bei diesem Schnipsel fällt auf, dass
Delphi-Quellcode:
myObj := nil
irgendwie aus dem Rahmen fällt. Diese Variable bezieht sich auf das Objekt selbst (hält also eine Klasseninstanz). Wenn man die auf Nil setzt, hat das keine Auswirkung auf das Objekt selbst.

Wenn man myObj.Free aufruft bevor myIntf1 und myIntf2 auf nil gesetzt sind, wird das Objekt freigegeben (quasi gelöscht) und bei einem Zugriff auf myIntf1 oder myIntf2 kann/wird es knallen.

Eigentlich ist die Klassenvariable also hier fehl am Platz und man würde das eher so schreiben:
Delphi-Quellcode:
myIntf1 := TMyObj.Create;
myIntf2 := myIntf1;
..
myIntf1 := nil;
myIntf2 := nil;
Hier arbeitet man nur noch mit den Interfaces und es ist egal, was da für eine Klasse instanziiert wurde.
Wenn alle Referenzen wegfallen, wird das Objekt freigegeben.


Wenn Du aber von TInterfacedPersistend ableitest, gibt es keine Referenzzählung und keine automatische Freigabe des Objektes.
Daher musst Du (um ein Speicherleck zu vermeiden) das Objekt wieder selbst freigeben - i.d.R. auf der Ebene, wo es erzeugt wurde.
Dann kümmerst Du Dich ganz normal selbst um die Lebenszeit der Objekte und nutzt die Interfaces nur zur Vereinheitlichung der Klassenstrukturen.

So müssen nicht Klassen zueinander passen, sondern nur Klassenteile.

EWeiss 11. Sep 2017 21:24

AW: Object (Interface) <> nil
 
So weit habe ich das verstanden.
Verwende jetzt TInterfacedObj Mein Interface ist Nil und Destroy wird automatisch aufgerufen.

Dann sollte das so stimmen. ;)
Danke dir.

gruss

stahli 11. Sep 2017 21:40

AW: Object (Interface) <> nil
 
:thumb:

Jetzt könntest Du ggf. noch ohne den Callback auskommen.
Du bekommst ja jetzt im destructor mit, dass das Objekt freigegeben wird.
Jetzt könntest Du auch dort
Delphi-Quellcode:
PopUpMenu := nil;
ausführen.

Ist aber Geschmacksache und würde sofort nicht mehr funktionieren, wenn durch Änderungen am Projekt irgendwann doch noch irgendwo eine Referenz auf das Objekt hängen würde.

EWeiss 11. Sep 2017 21:54

AW: Object (Interface) <> nil
 
Zitat:

Jetzt könntest Du auch dort PopUpMenu := nil; ausführen.
Nein kann ich nicht weil PopUpMenu := Nil ohne Callback in der Hauptanwendung nicht ankommt.
In der DLL nutzt es auch nichts denn PopUpMenu ist eine Variable in den Main App

Davon ab habe noch genug andere Problem mit den Events trotz SubClasses will nicht so recht.
Irgendwas ist immer... schwierig ein Menu zu emulieren. Na ja hab ja sonst nix zu tun :)

sind jetzt schon 1600 zeilen.

gruss

stahli 11. Sep 2017 21:59

AW: Object (Interface) <> nil
 
Ok, Hauptsache es funktioniert. :thumb:

EWeiss 11. Sep 2017 22:02

AW: Object (Interface) <> nil
 
Zitat:

Zitat von stahli (Beitrag 1380852)
Ok, Hauptsache es funktioniert. :thumb:

Dito und Danke nochmal.. an alle die mitgeholfen haben.

gruss

EWeiss 13. Sep 2017 18:52

AW: Object (Interface) <> nil
 
Habe doch noch ein Problem

Beim erstellen des Menu wird der FRefCount hochgesetzt also auf 1
Wie kann ich jetzt feststellen warum dieser nicht runtergezählt wird.

Ich bin der Meinung das alles freigegeben wird aber die Referenz schaltet nicht runter finde das Problem nicht.
OK. Denke mal.. hat sich erledigt.

gruss


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:43 Uhr.
Seite 4 von 4   « Erste     234   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz