AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Wie kann ich feststellen, ob Sub-Klasse schon gelöscht ist
Thema durchsuchen
Ansicht
Themen-Optionen

Wie kann ich feststellen, ob Sub-Klasse schon gelöscht ist

Ein Thema von norwegen60 · begonnen am 14. Sep 2023 · letzter Beitrag vom 15. Sep 2023
Antwort Antwort
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#1

AW: Wie kann ich feststellen, ob Sub-Klasse schon gelöscht ist

  Alt 14. Sep 2023, 14:28
[DELPHI]
for i := 0 to TestList.Count do
if (TestList[i].Values <> nil) then
FreeAndNil(TestList[i].Values);
Das habe ich als erstes probiert. Das lässt Delphi nicht zu
Code:
[DCC Fehler] uQualHelper.pas(187): E2197 Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden
  Mit Zitat antworten Zitat
jziersch

Registriert seit: 9. Okt 2003
Ort: München
240 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Wie kann ich feststellen, ob Sub-Klasse schon gelöscht ist

  Alt 15. Sep 2023, 09:06
Zitat:
Es kann es sein, dass mehrere TTest auf das gleich TValues zeigen
In diesem Fall würde ich eine separate Liste anlegen in denen die TValues + eine eindeutige ID (Cardinal) gespeichert werden. In deiner TTest Klasse hast Du dann nur diese ID.
Jede neues TValue erzeugt eine neue ID mit Inc(LastID).
Wenn Du ein TValue löscht werden die IDs automatisch ungültig. Dies Liste ist sortiert, da neue Values hinten angehängt werden. Wert-Lücken ergeben sich durch das löschen.

Du kannst das TValue zu jeder ID schnell mit List.BinarySearch suchen - und wenn es nicht gefunden wird, ist der Wert eben ungültig.

Anmerkung - müsste es nicht heißen for i:=0 to List-Count-1 do ?
WPCubed GmbH
Komponenten für Delphi:
WPTools, wPDF, WPViewPDF
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.366 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Wie kann ich feststellen, ob Sub-Klasse schon gelöscht ist

  Alt 15. Sep 2023, 09:31
Servus,

Es kann es sein, dass mehrere TTest auf das gleich TValues zeigen

Jetzt will ich in allen TTest, denen ein TValues zugewiesen ist, dieses löschen
d.h. TTEst legt die Instanz von TValues nicht an, sondern bekommt die zugewiesen oder holt die sich wo her. Bisher hat sich bei mir folgendes bewährt:
Wer Objekte anlegt, der gibt die auch wieder frei (keine Regel ohne Ausnahme). D.h. du kannst so vorgehen wie jziersch vorschlägt. Oder du sagst etwas mehr darüber wie die KLassen zueinander finden.

ein FreeAndNil funktioniert nicht, weil die Funktion eben einen Var-Parameter braucht. Lösen kannst Du das mit einem Zweizeiler:

Delphi-Quellcode:
for i := 0 to TestList.Count do
  if (TestList[i].Values <> nil) then
  begin
    TestList[i].Values.Free;
    TestList[i].Values := nil;
  end
allerdings klappt das im weiteren Verlauf nicht weil:
Es kann es sein, dass mehrere TTest auf das gleich TValues zeigen
Daher bleibt imho nix anderes als eine zentrale Liste / Klasse, die die Lebensdauer von TValues überwacht, erstellt, freigibt. Wenn Du zum drum herum noch das eine oder andere sagen kannst, dann kann man hier vielleicht auch noch den einen oder anderen Tipp geben.

Grüße
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Wie kann ich feststellen, ob Sub-Klasse schon gelöscht ist

  Alt 15. Sep 2023, 10:03
Eine ziemlich bequeme Möglichkeit wäre es, die Klassen von TComponent abzuleiten und mit FreeNotification zu arbeiten. Das könnte dann in etwa so aussehen:
Delphi-Quellcode:
type
  TValues = class(TComponent)
  public
    x: Double;
    y: Double;
  end;

  TTest = class(TComponent)
  public
    Name: String;
  private
    FValues: TValues;
    procedure SetValues(const Value: TValues);
  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  public
    property Values: TValues read FValues write SetValues;
  end;

procedure TTest.Notification(AComponent: TComponent; Operation: TOperation);
begin
  if (AComponent = FValues) and (Operation = opRemove) then
    FValues := nil;
  inherited;
end;

procedure TTest.SetValues(const Value: TValues);
begin
  if FValues <> Value then
  begin
    if FValues <> nil then
      FValues.RemoveFreeNotification(Self);
    FValues := Value;
    if FValues <> nil then
      FValues.FreeNotification(Self);
  end;
end;
Die verbleibenden public Fields würde ich aber gleich auch noch in Properties umwandeln.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  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 23:52 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