AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Object (Interface) <> nil

Ein Thema von EWeiss · begonnen am 11. Sep 2017 · letzter Beitrag vom 13. Sep 2017
Antwort Antwort
EWeiss
(Gast)

n/a Beiträge
 
#1

AW: Object (Interface) <> nil

  Alt 11. Sep 2017, 20:02
Ich habe es jetzt so gemacht.

Anwendung:
Delphi-Quellcode:
type
  TPopUpState = (OnPopupDestroyed);
  POPUPSTATECALLBACK = procedure(PopUpState: TPopUpState); stdcall;
  PopUpMenu := CTRL_PopUpMenuCreate(PopUpCallback);
Delphi-Quellcode:
procedure PopUpCallback(PopUpState: TPopUpState); stdcall;
begin
  case PopUpState of
    OnPopupDestroyed:
      PopUpMenu := nil;
  end;
end;
DLL:
Delphi-Quellcode:
var
  PopUpCallback : POPUPSTATECALLBACK;
Delphi-Quellcode:
function CTRL_PopUpMenuCreate(callback: POPUPSTATECALLBACK): ISkinPopUpMenu; stdcall;
begin

  result := TSkinPopUpMenu.Create();
  PopUpCallback := callback;
end;
Wenn Nil..
Delphi-Quellcode:
if SkinPopUpMenu = nil then
  PopUpCallback(OnPopupDestroyed);
funktioniert ganz gut kann es so belassen.
Danke für die Hilfe.

gruss
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.355 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Object (Interface) <> nil

  Alt 11. Sep 2017, 20:17
Ok, fein.
Wenn es so klappt, ist es schön.
Ich will auch nicht nochmal zur Verwirrung beitragen, aber vielleicht kannst Du mal noch nach zwei Dingen schauen:

Hast Du Deine Klasse von TInterfacedPersistent abgeleitet oder von TInterfacedObject?
Wird Dein Destructor des Objektes irgendwann aufgerufen?

Ich vermute, dass Dein Objekt aktuell nicht freigegeben wird. Das wäre nicht unbedingt ein Drama, aber erzeugt dann halt ein Speicherleck.

Wenn Du Dich darum noch kümmern willst, könnte man dem noch nachgehen...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#3

AW: Object (Interface) <> nil

  Alt 11. Sep 2017, 20:22
Zitat:
Hast Du Deine Klasse von TInterfacedPersistent abgeleitet oder von TInterfacedObject?
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
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.355 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Object (Interface) <> nil

  Alt 11. Sep 2017, 20:25
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.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#5

AW: Object (Interface) <> nil

  Alt 11. Sep 2017, 20:32
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

Geändert von EWeiss (11. Sep 2017 um 20:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.355 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Object (Interface) <> nil

  Alt 11. Sep 2017, 21:17
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 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.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (11. Sep 2017 um 21:20 Uhr)
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#7

AW: Object (Interface) <> nil

  Alt 11. Sep 2017, 21:24
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
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz