AGB  ·  Datenschutz  ·  Impressum  







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

TListBox Objekte löschen

Ein Thema von martin_ · begonnen am 20. Okt 2009 · letzter Beitrag vom 20. Okt 2009
Antwort Antwort
martin_

Registriert seit: 19. Mai 2008
Ort: Österreich
89 Beiträge
 
#1

TListBox Objekte löschen

  Alt 20. Okt 2009, 10:58
Hallo,
ich verwende zum Anzeigen die TListBox Komponente. Ein Objekt wird mit
 lst1.AddItem('String',cont); zur Listbox (lst1) hinzugefügt. cont ist ein eigens Objekt der Klasse TObject. Meine Frage lautet gibt es bei einer ListBox so etwas wie OwnesObject bei einer TObjectList? Das Problem ist nämlich folgendes: Meiner Meinung erzeugt die Listbox für jedes hinzugefügte Objekt eine Kopie. Wird das ursprüngliche Objekt (cont) an einer anderen Stelle freigegeben, ist es in der Liste noch vorhanden. Nur kann ich es nicht auf der Liste abfragen welchen Zustand es hat (zb. wird das Objekt in der Liste nicht nil, obwohl es freigegeben wurde. Das Objekt selbst ist aber nil und kann dort auch so abgefragt werden).
Für das KeyPress Ereignis habe ich zb. folgenden Code für die Abfrage:
Delphi-Quellcode:
var
  obj : TObject;
begin
  if key = Char(VK_RETURN) then
  begin
    obj := lst1.Items.Objects[lst1.ItemIndex];

    if obj = nil then
    begin
      ShowMessage(' obj = nil');
    end;

    if obj is MyCont then
    begin
     ShowMessage(MyCont(obj).Value);
    end;

  end;
end;
Wobei das hinzugefügte Objekt für den Test so
Delphi-Quellcode:
  MyCont = class
    Value : string;
  end;
aussieht. Kurze Zusammenfassung: Objekt einer Listbox wird an einer anderen Stelle gelöscht, wie funktioniert die Abfrage?
  Mit Zitat antworten Zitat
Benutzerbild von mleyen
mleyen

Registriert seit: 10. Aug 2007
609 Beiträge
 
FreePascal / Lazarus
 
#2

Re: TListBox Objekte löschen

  Alt 20. Okt 2009, 11:05
Hi,

Zitat von martin_:
aussieht. Kurze Zusammenfassung: Objekt einer Listbox wird an einer anderen Stelle gelöscht, wie funktioniert die Abfrage?
soweit ich weiß, kannst du das nicht direkt Abfragen.
Das Problem hier ist einfach, das du mehrere Referenzen auf ein Objekt hast.
Diese Referenzen musst du alle 'nillen', um jedes prüfen zu können, ob es noch existiert.

Das einzige was du machen könntest wäre evtl auf eine andere Referenz zu prüfen, bei der sichergestellt ist, das sie genillt wurde.
  Mit Zitat antworten Zitat
Muetze1
(Gast)

n/a Beiträge
 
#3

Re: TListBox Objekte löschen

  Alt 20. Okt 2009, 11:07
Zitat von martin_:
Das Problem ist nämlich folgendes: Meiner Meinung erzeugt die Listbox für jedes hinzugefügte Objekt eine Kopie. Wird das ursprüngliche Objekt (cont) an einer anderen Stelle freigegeben, ist es in der Liste noch vorhanden.
Tja, aber das ist wirklich auch nur deine Meinung. Delphi kann nicht einfach Objekte kopieren, hier gibt es keine Copy Constructoren wie bei C++. Das Objekt existiert nur einmal, die Instanzenvariablen wie cont sind nur Zeiger auf das eigentliche Objekt im Speicher. Beim Hinzufügen wird nur dieser Pointer in die Listbox eingetragen. Somit hast du 2 Pointer die auf den gleichen Speicher, ergo das gleiche Objekt zeigen. Das ist eine 1:n Beziehung. Wenn du nun das Objekt freigibst, z.B. mit .free, dann ist das Objekt im Speicher nicht mehr vorhanden, aber cont und Objects[] zeigen noch dahin wo es mal war. Wenn du nun mit FreeAndNil() arbeitest wird zumindest eine Stelle (cont) sogar noch auf einen definierten Wert gesetzt, aber der andere Pointer nicht.

Grundlegend ist dein Problem ein Designproblem. Du missachtest hier vor allem die Grundregel der Trennung von Code und Daten. Die Objekte müsstest du dir irgendwo unabhängig von der Darstellung halten. Damit ist immer gewährleistet wo du deine Informationen gesichert holen kannst, da der Ort gepflegt wird und die Referenz darstellt. Damit hast du eine zentrale und Oberflächen-unabhängige Stelle wo du Daten anlegst, veränderst und freigibst. Damit hast du dort auch die Möglichkeiten eine Aktualisierung der Oberfläche anzustoßen, etc. Wenn das der Fall ist, stellt sich deine Frage nicht mehr, da du niemals in der ListBox nachschauen brauchtest nach dem Objekt.
  Mit Zitat antworten Zitat
martin_

Registriert seit: 19. Mai 2008
Ort: Österreich
89 Beiträge
 
#4

Re: TListBox Objekte löschen

  Alt 20. Okt 2009, 12:01
Danke für die wirklich guten Antworten, die haben mir sehr genutzt.

Ich habe noch eine allgemeine Frage zu der Beziehung: auf ein Objekt zeigen zwei oder mehrere Pointer. Wie wird das Prinzipiell in anderen Sprachen allgemein gehandhabt. Gibt es dort Möglichkeiten herauszufinden ob/wann sich das Objekt verändert hat?
  Mit Zitat antworten Zitat
Benutzerbild von mleyen
mleyen

Registriert seit: 10. Aug 2007
609 Beiträge
 
FreePascal / Lazarus
 
#5

Re: TListBox Objekte löschen

  Alt 20. Okt 2009, 12:41
Soweit ich weiß nicht, zumindest wär mir keine bekannt. (Wär ja auch irgendwo total overheaded, andauernd jede Referenz zu prüfen)

Ich weiß nur zu gut, dass es manchmal (gerade aus performancegründen) schnell und einfach geht mehrere Referenzen auf ein Objekt zeigen zu lassen. Nur wie Muetze1 schon sagt, ist das irgendwo nicht sauber.

[vorsicht, jetzt kommt was ganz abstruses]
Du könntest anstatt mit einer Referenz mit Referenzen auf eine Referenz zeigen, welche wiederum auf das Objekt zeigt.
Wo auch immer im Code du das Objekt jetzt freigibst, musst du nur die Referenz nillen, die auf das Objekt zeigt.
Überall anders kannst du jetzt über die Referenz, die auf die Objekt-Referenz zeigt, prüfen, ob das Objekt noch existiert.
(Tipp am Rande: Sowas besser nur in eigenen Komponenten machen, die sich kein anderer anschaut. Das artet nur in Fragen aus )
  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 10:27 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