Hallo,
wie kann ich feststellen ob ein bestimmtes Object bereits gelöscht wurde?
Beispiel:
Das Object wird angelegt mit
obj:=TButton.Create(Form1);
wenn nun das Formular Form1 gelöscht wird, wird automatisch auch der Button gelöscht.
Wie kann ich festellen ob der Button noch existiert oder ob er bereits freigegeben wurde?
Vielen Dank
Joachim
             
            
              
              
              
            
            
           
          
            
            
              Hallo Joachim,
mit der Abfrage
if Assigned(obj) then
 // Object existiert noch
Gruß Mike
             
            
              
              
              
            
            
           
          
            
            
              Hallo,
mit der Abfrage
if Assigned(obj) then
// Object existiert noch
das stimmt so nicht.
assigned prüft nicht, ob das Objekt noch existiert, sondern ob die Objektvariable nil ist. Führ einmal folgenden Code aus:
var
 B: TButton;
procedure TForm1.Button1Click(Sender: TObject);
begin
 Form2 := TForm2.Create(nil);
 B := TButton.Create(Form2);
 B.Parent := Form2;
 B.Top := 10;
 B.Left := 10;
 Form2.ShowModal;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
 Form2.Free;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
 if Assigned(B)then ShowMessage('ist assigned') 
 else ShowMessage('ist not assigned');
end;
Nun klicke der Reihe nach
- Button1 (Form erzeugen, ButtonVariable zuweisen und Form 1mal zeigen)
- Button2 (Form zerstören)
- Button3 (Zuweisung prüfen)
hier bleibt B immer noch „assigned“.
Aus diesem Grund ist es auch gute Praxis, nach dem Zerstören eines Objekts die Objektvariable auf nil zu setzen.
Ich würde im vorliegenden Fall ganz normal in einem try-except-Block über die Variable auf das Objekt zugreifen und bei Auslösen der Exception vom Typ EAccessViolation die Variable auf nil setzen.
procedure TForm1.Button3Click(Sender: TObject);
begin
 if Assigned(B)then ShowMessage('ist assigned') else ShowMessage('ist not assigned');
 try
 B.Top := 20;
 except
 on e: EAccessViolation do B := nil;
 end;
end;
wird jetzt der Button3 gedrückt (nach Button1 und 2), so erscheint zunächst „is assigned“. Dann wird die Exception ausgelöst und bei einem weiteren Druck auf Button3 ist es dann „is not assigned“. Dafür sind Exception-Schutzblöcke da.
Gruss, Niels
             
            
              
              
              
            
            
           
          
            
            
              Hallo,
probier einen Zugriff auf ein Feld des Objekts. Wenn das Objekt nicht mehr existiert, gibt es eine Zugriffsverletzung. Damit die nicht zum Programmabbruch führt, machst Du das in einem try-except-Block:
function ObjExists(Obj:TObject):Boolean;
begin
 try
 result := (Obj.ClassName "Ö")
 except
 on exception do result := FALSE
 end;
end;
Gruß,
Jochen
             
            
              
              
              
            
            
           
          
            
            
              Hallo Jochen
probier einen Zugriff auf ein Feld des Objekts. Wenn das
Objekt nicht mehr existiert, gibt es eine Zugriffsverletzung.
Auf die Idee mit dem Try-Except Block bin ich auch schon gekommen, ich dachte nur es gibt vielleicht auch eine „saubere“ Lösung.
Vielen Dank, Joachim
             
            
              
              
              
            
            
           
          
            
            
              Hallo,
Auf die Idee mit dem Try-Except Block bin ich auch schon
gekommen, ich dachte nur es gibt vielleicht auch eine
„saubere“ Lösung.
der Try-Except-Block ist die saubere Lösung. Nur dadurch hast du die Garantie, alle auftretenden Exceptions abzufangen. Die Alternative wäre je nach Programm massenweise if-Abfragen einzufügen, durch die der Code zerstückelt wird. Auch nicht gerade elegant, oder? Try-Except macht es möglich, die Fehlerbehandlung vom laufenden Code zu trennen, wodurch das Programm insgesamt übersichtlicher wird (wenn man’s richtig macht).
Gruss, Niels
             
            
              
              
              
            
            
           
          
            
            
              Hallo Niels
der Try-Except-Block ist die saubere Lösung
Das Problem bei dieser Lösung ist, dass bei eingeschaltetem Debugger immer an dieser Stelle eine lästige Fehlermeldung kommt.
Ich habe übrigens unter http://www.delphipraxis.net/topic17825_isobject+iscl… eine interessante Diskusion zu diesem Thema gefunden.
Viele Grüße, Jochim Knöll
             
            
              
              
              
            
            
           
          
            
            
              Hallo,
der Try-Except-Block ist die saubere Lösung
Das Problem bei dieser Lösung ist, dass bei eingeschaltetem
Debugger immer an dieser Stelle eine lästige Fehlermeldung
kommt.
Unter Tools, Debugger-Optionen, BS-Exceptions unten
Integrierte Fehlersuche deaktivieren!
Es lassen sich auch einzelne Exceptions aus der integrierten Fehlersuche rausnehmen.
Ich habe übrigens unter
http://www.delphipraxis.net/topic17825_isobject+iscl…
eine interessante Diskusion zu diesem Thema gefunden.
Wow, ich hätte nicht gedacht, daß das Problem sooo schwierig ist. Wie dem auch sei, ich favorisiere und empfehle, in der Programmstruktur logisch sicherzustellen, daß
- Referenzen auf freigegebene Objekte IMMER auf NIL gesetzt werden
- Objekte mit noch aktiven abhängigen Referenzen NICHT freigegeben werden
Dabei kann es u.U. nötig sein, Daten/Objekte besser zu kapseln und ggf. an Kopien zu arbeiten.
Viele Grüße, Jochen
             
            
              
              
              
            
            
           
          
            
            
              Hallo Joachim,
der Try-Except-Block ist die saubere Lösung
Das Problem bei dieser Lösung ist, dass bei eingeschaltetem
Debugger immer an dieser Stelle eine lästige Fehlermeldung
kommt.
dann schalte diese Funktion doch einfach ab:
Menu: Tools -> Debugger-Optionen
dort den Reiter „BS-Exceptions“ wählen und „behandelt von“ auf „Anwenderprogramm“ stellen.
Gruß, Niels
             
            
              
              
              
            
            
           
          
            
            
              Hallo
Falsch - es muss heißen…
 if Assigned(Object) and (Object nil) then
 bAssigned := true
 else
 bAssigned := false;
Gruß
             
            
              
              
              
            
            
           
          
            
            
              Hallo,
Falsch - es muss heißen…
if Assigned(Object) and (Object nil) then
bAssigned := true
else
bAssigned := false;
also zum Einen: wo muss es das heißen? Ich finde keine Stelle, an der dieser Code passen würde.
und zum Anderen:
wie oben bereits erwähnt, prüft die Funktion assigned(Obj) ob das Object nil ist. Dein Code heißt also im Prinzip:
if (Object nil) and (Object nil) then
…
Das scheint mir aber irgendwie nicht sehr intelligent…
Gruss, Niels