AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Die Delphi-IDE Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

Ein Thema von Getox · begonnen am 27. Jun 2017 · letzter Beitrag vom 27. Jun 2017
Antwort Antwort
Getox

Registriert seit: 28. Dez 2012
155 Beiträge
 
Delphi XE3 Professional
 
#1

Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

  Alt 27. Jun 2017, 14:18
Hallo mal wieder.

Ich habe ein Problem mit einem Objekt, dass freigegeben wurde, wo aber die variable nicht auf nil gesetzt wurde.

Code:
procedure TFormToast.showMessage(sMitteilung: String; aForm: TForm);
begin
  if Assigned(messageBoxToast) and (aCenterForm <> aForm) then
  begin
    messageBoxToast.HideAll;
    FreeAndNil(messageBoxToast);
  end;

  if not Assigned(messageBoxToast) then
  begin
    messageBoxToast := TAdvSmartMessageBox.Create(aForm);
    aCenterForm := aForm; //aCenterForm ist Klassenvariable
    messageBoxToast.DisplayLocation := dlbottomCenter;
    messageBoxToast.DisplayRelative := drForm;
  end;

  with MessageBoxToast.Messages.Add do
  begin
    Text := sMitteilung;
    Show;
  end;
end;
Der Sinn dahinter:
Es sollen an verschiedenen Stellen im Programm so Infoboxen erscheinen, die ich ganz im Android-Style einfach Toast nenne. Diese Nachrichten werden am Owner ausgerichtet, welcher immer ein anderes Form sein kann - aber nicht muss. Deshalb merke ich mir in einer Klassenvariable das übergebene Form und wenn ein anderes rein kommt, wird die TAdvSmartMessageBox freigegeben und mit dem neuen Form als Owner wieder erzeugt - an dem dann wieder die Nachrichten ausgerichtet werden.

jetzt habe ich das Problem, dass die übergebenen Forms oft (nicht immer) außerhalb wieder freigegeben werden und somit dürfte auch das Objekt hinter der Variable MessageBoxToast automatisch vom Owner freigegeben werden, ohne dass die Variable selber auf nil gesetzt wird.

Wenn ich jetzt eine neue Instanz des vorherigen Forms übergebe, sagt die Abfrage "(aCenterForm <> aForm)" false weil es angeblich das gleiche Form ist (trotz neuer Instanz) und die Variable von MessageBoxToast ist auch noch irgendwie assigned, weil sie ja noch nicht auf nil gesetzt wurde.

Dann scheint irgendwie im Speicher auf den MessageBoxToast zeigt nur blödsinn zu stehen, auf den ich zugreifen will und dann knallt es.

Wie kann ich also überprüfen, ob hinter der (nicht auf nil gestetzten) Variable noch ein intaktes Objekt hängt?
Ist ein Nilpferd ein Pferd, das nicht vorhanden ist?
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

  Alt 27. Jun 2017, 14:25
Wie kann ich also überprüfen, ob hinter der (nicht auf nil gestetzten) Variable noch ein intaktes Objekt hängt?
Kurz und schmerzlos: Gar nicht ohne ekelhafte Hacks.

Stattdessen könntest du aber deinen Ansatz verfeinern, indem du beim Zuweisen des Formulars das OnDestroy Event einer Methode deiner TAdvSmartMessageBox Instanz zuweist und dort für das "nil-en" der entsprechenden Variable sorgst. Das wäre jetzt nur der einfachste Ansatz (welcher Probleme machen könnte, wenn du das OnDestroy Event bereits für irgendetwas Anderes im Formular verwendest, etc.).

Alternativ könntest du auch allen betroffenen Forms ein Interface verpassen, über welches du dein Destroy-Event sauber registrieren könntest. Gibt viele Möglichkeiten ... wichtig ist, dass du über irgendeinen Callback mitbekommst, wenn das Formular zerstört wird.

Edit: Dein messageBoxToast solltest du dann ggfls. auch selbst verwalten (also AOwner = nil ).
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl (27. Jun 2017 um 14:28 Uhr)
  Mit Zitat antworten Zitat
Getox

Registriert seit: 28. Dez 2012
155 Beiträge
 
Delphi XE3 Professional
 
#3

AW: Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

  Alt 27. Jun 2017, 14:44
Ich muss das Übergebene Form als Owner setzen, damit die Nachrichten ja daran ausgerichtet werden. Wenn ich als Owner nil übergebe und das selber verwalten möchte, erscheinen die Nachrichten irgendwo ScreenCentered und dass sollen sie ja eben nicht.

Leider kann ich auch nicht einfach zur Laufzeit den Owner wechseln...

Unsere Forms benutzen leider so gut wie alle das "onDestroy" event, so dass ich es nicht einfach neu zuweisen kann.

Bei jedem Form ein Interface hinzufügen würde klappen wäre aber auch wieder komisch umständlich Ich wollte ja im Grunde eine Unit bauen, wo man mit minimalem aufwand (meist 1 Funktion mit 2 Parametern) überall im Programm diese Nachrichten erzeugen kann.
Ist ein Nilpferd ein Pferd, das nicht vorhanden ist?
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: München
11.412 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

  Alt 27. Jun 2017, 15:09
Unsere Forms benutzen leider so gut wie alle das "onDestroy" event, so dass ich es nicht einfach neu zuweisen kann.
Du kannst auch den destructor Destroy; override; nutzen

......
Daniel W.
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
529 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

  Alt 27. Jun 2017, 15:15
Ich würde es vielleicht so machen:

Alternative 1
In jedem form.create auch gleich die box mit erzeugen, die Box unsichtbar setzten.
Wenn die Box angezeigt werden soll, Text zuweisen und showmodal;
Wir das Formular geschlossen dann auch freeandnil für die Box.

Alternative 2
Man könnte auch eine Box für alle Meldungen erzeugen und die wird dann immer nur mit Text versorgt und angezeigt.
Anstatt Owner könnte die Box dann eine Variable FromForm haben, eben die Form die die Box aufgerufen hat, müsste dann bei Aufruf gesetzt werden.
Positionieren sollte nicht das Problem sein, geht auch über FromForm. Natürlich geht dann nur eine Meldung zur Zeit.

Würde wohl Alternative 2 einsetzten.
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.934 Beiträge
 
Delphi 12 Athens
 
#6

AW: Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

  Alt 27. Jun 2017, 15:21
Da es sich sowohl bei messageBoxToast und aCenterForm um Nachfahren von TComponent handelt, kannst du dich über die Freigabe dieser Instanzen mittels FreeNotification benachrichtigen lassen.

Delphi-Quellcode:
procedure TFormToast.Notification(AComponent: TComponent; Operation: TOperation);
begin
  if Operation = opRemove then
  begin
    if AComponent = messageBoxToast then
    begin
      messageBoxToast := nil;
    end;
    if AComponent = aCenterForm then
    begin
      aCenterForm := nil;
    end;
  end;
end;

procedure TFormToast.showMessage(sMitteilung: String; aForm: TForm);
begin
  if Assigned(messageBoxToast) and (aCenterForm <> aForm) then
  begin
    messageBoxToast.HideAll;
    aCenterForm.RemoveFreeNotification(Self);
    messageBoxToast.RemoveFreeNotification(Self);
    FreeAndNil(messageBoxToast);
  end;

  if not Assigned(messageBoxToast) then
  begin
    messageBoxToast := TAdvSmartMessageBox.Create(aForm);
    aCenterForm := aForm; //aCenterForm ist Klassenvariable
    messageBoxToast.DisplayLocation := dlbottomCenter;
    messageBoxToast.DisplayRelative := drForm;
    aCenterForm.FreeNotification(Self);
    messageBoxToast.FreeNotification(Self);
  end;
...
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Getox

Registriert seit: 28. Dez 2012
155 Beiträge
 
Delphi XE3 Professional
 
#7

AW: Prüfen ob ein Objekt freigegeben wurde (Assigned geht nicht)

  Alt 27. Jun 2017, 16:07
Da es sich sowohl bei messageBoxToast und aCenterForm um Nachfahren von TComponent handelt, kannst du dich über die Freigabe dieser Instanzen mittels FreeNotification benachrichtigen lassen.
Vielen vielen Dank! Das war des Rätsels Lösung!

Ich musste nur noch ein inherited; unten in die Notification -Prozedur hinzufügen, weil sonst alles gehangen hat, aber nun läuft es.
Ist ein Nilpferd ein Pferd, das nicht vorhanden ist?
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 09:58 Uhr.
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