Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Instanz eines Objektes auf existenz Prüfen (https://www.delphipraxis.net/14547-instanz-eines-objektes-auf-existenz-pruefen.html)

Skript 11. Jan 2004 12:19


Instanz eines Objektes auf existenz Prüfen
 
Hallooohoo,

Ich habe das Problem, dass ich die Instanz eines Objektes überprüfen möchte ob das Ursprungsobjekt noch existiert, bzw. den Inhalt der Pointer Adresse überprüfen ob überhaupt noch Inhalt vorhanden ist.
Aaaalso ich habe ein Objekt der Klasse TEgal:
Delphi-Quellcode:
MeinObjekt := TEgal.Create;
Jetzt mache ich eine Instanz des Objektes mit einem untypisierten Pointer:
Delphi-Quellcode:
MeineInstanz: Pointer;
MeineInstanz := MeinObjekt;
Jetzt vernichte ich das Ursprungsobjekt:
Delphi-Quellcode:
FreeAndNil(MeinObjekt);
Die .Free Methode sollte ja den Speicher freigeben
Und jetzt möchte ich gerne ohne Exeption-Handling anhand der Instanz überprüfen ob das Ursprungsobjekt noch vorhanden ist, so im Sinne von:
Delphi-Quellcode:
if not Assigned(TEgal(MeineInstanz)) then Exit
Aber irgendwie klappt das nicht :roteyes: , gibt es denn eine Möglichkeit, zu überprüfen ob die Adresse der Instanz noch gültig ist, bzw. inhalt hat? Oder muss ich hier mit Typisiereten Pointern arbeiten wie:
Delphi-Quellcode:
MeineInstanz: ^TEgal;
MeineInstanz := @MeinObjekt;
FreeAndNil(MeinObjekt);
if not Assignet(MeineInstanz^) then Exit;
So, ich hoffe ich habe das jetzt so unverständlich wie möglich geschrieben :stupid:

Wie macht ihr Objektinstanzen und Prüft auf derer Existenz?

Gruss & vielen Dank

Jelly 11. Jan 2004 12:28

Re: Instanz eines Objektes auf existenz Prüfen
 
Hallo,

schon mal
Code:
if not (MeinObjekt=Nil) then ...
probiert?

Gruß,
Tom

Skript 11. Jan 2004 13:00

Re: Instanz eines Objektes auf existenz Prüfen
 
Hallo,

hmm, das ist mir eigentlich klar, dass wenn ich:
Delphi-Quellcode:
FreeAndNil(MeinObjekt);
mache, MeinObjekt = nil, True ist, aber danke :) Assigned(...) überprüft ja das selbe.

Mein Problem ist wirklich dann, wenn ich eine Instanz will, also zum Beispiel habe ich mein MeinObjekt erstellt und will das jetzt einem Formular übergeben, welches mir die Daten dieses Objektes ausgibt:
Delphi-Quellcode:
MeinFormular = class(TMeinFormular)
  MeineInstanz: TEgal; // Instanz des Objektes welchen Daten angezeigt werden sollen

  procedure Anzeigen;
end;
Also erstelle ich mein Objekt und übergebe es dem Formular:
Delphi-Quellcode:
MeinObjekt := TEgal.Create;

MeinFormular.MeineInstanz := MeinObjekt;
Dann möchte ich in der Anzeigen Prozedur die Daten des Instanzobjektes anzeigen:
Delphi-Quellcode:
procedure MeinFormular.Anzeigen
begin
  Panel.Caption := MeinObjekt.Name;
end;
So, und wenn ich jetzt irgendwo in meinem Code mein Ursprungsobjekt vernichte:
Delphi-Quellcode:
FreeAndNil(MeinObjekt);
Besitzt das Formular immer noch die Instanz. Wie kann ich jetzt in der Anzeigen-Prozedur überprüfen ob die Instanz noch gültig ist?
Delphi-Quellcode:
procedure MeinFormular.Anzeigen
begin
  if Assigned(MeineInstanz) then Exit;
  // oder:
  if Assigned(TEgal(MeineInstanz)) then Exit;

  Panel.Caption := MeinObjekt.Name;
end;
Funktionieren nämlich nicht, bzw. die Instanz zeigt ja immernoch auf was...
und wie zum Herrgottdonnerunddoria mach ich jetzt das? :roteyes: :-D

Jelly 11. Jan 2004 13:26

Re: Instanz eines Objektes auf existenz Prüfen
 
Zitat:

Zitat von Skript
Einerseits schreibst du
Delphi-Quellcode:
MeinFormular = class(TMeinFormular)
Andererseits
Delphi-Quellcode:
MeinObjekt := TEgal.Create;

Also da blick ich nicht wirklich durch. Ist MeinFormular nun eine Klassendefinition oder die Variable über die du deine Klasse ansprichst.

Aber wenn du mit FreeAndNil (MeinFormular) dein Forumular im Speicher wieder freigibst, wie willst du dann überhaupt noch auf die Instanz MeinFormular.MeineInstanz zugreifen :?:

Ich glaub ich hab dein Problem immer noch nicht ganz verstanden. Steh wohl irgenwie auf dem berühmten Schlauch :roll:
Gruss,
Tom

Skript 11. Jan 2004 13:39

Re: Instanz eines Objektes auf existenz Prüfen
 
Hiho,

uh, da hab ich was falsch geschrieben und anders gemeint, sorry Tom :roll:
Delphi-Quellcode:
TMeinFormular = class(TForm)
  MeineInstanz: TEgal; // Instanz des Objektes welchen Daten angezeigt werden sollen

  procedure Anzeigen;
end;

// und dann die Variable dazu
MeinFormular: TMeinFormular;
Wie Gesagt erstelle ich dann das Formular, übergebe ihm das MeinObjekt:
Delphi-Quellcode:
MeinFormular.MeineInstanz := MeinObjekt;
Dann vernichte ich irgendwann im Code das MeinObjekt (nicht das MeinFormular!), mit
Delphi-Quellcode:
FreeAndNil(MeinObjekt);
Das Formular besitzt jedoch immer noch eine Instanz (MeineInstanz) auf das Objekt (MeinObjekt), welches aber auf einen Speicherbereich zeigt welcher ja durch FreeAndNil von MeinObjekt gelöscht wurde. Und jetz mein Problem: Wie konstrolliere ich in der Anzeigen Methode von MeinFormular, ob die Instanz noch gültig ist (Also ob Meinobjekt noch nicht vernichted wurde).
*fussvomschlauchnehm*, jetzt besser? :drunken:

Jelly 11. Jan 2004 16:08

Re: Instanz eines Objektes auf existenz Prüfen
 
Nachdem ich jetzt1 1 1/2 Stunden laufen war kann ich auch wieder klar denken und hab jetzt dein Problem erkannt :lol:

Was spricht denn dagegen, in der Routine wo du dein Objekt freigibts, auch gleich MeinFormular.MeineInstanz auf nil zu setzen. Oder gibts mehrere Formulare die auf TEgal einen Pointer setzen. Ausserdem, wo ist denn das Problem, alles in einen Try...except Block zu knallen.

Alternativ könntest du in deinem Constructor von TEgal einen Owner definieren, den du dann bei Create übergibts. Somit weiss deine TEgal Objekt von wem es erzeugt wurde.

Gruss,
Tom

Christian Seehase 11. Jan 2004 16:15

Re: Instanz eines Objektes auf existenz Prüfen
 
Moin Skript,

Delphi-Quellcode:
if not Assigned(TEgal(MeineInstanz)) then Exit
muss ja fehlschlagen, da Du ja nur den Pointer MeinObjekt mit FreeAndNil auf nil setzt.

Warum machst Du nicht einfach

Delphi-Quellcode:
if Assigned(MeinObjekt) then ...
und lässt die ganze Aktion mit dem untypisierten Pointer weg?
Wozu soll der überhaupt gut sein? :gruebel:

Skript 11. Jan 2004 17:11

Re: Instanz eines Objektes auf existenz Prüfen
 
Ich weiss nicht mehr wie ich mich noch ausdrücken soll :(

Versuch 1546 :)

Alles was ich will ist eine Instanz auf ein Objekt, über welche ich prüfen kann, ob das Ursprungsobjekt noch existiert. Ich kann da nicht ein Instanzobjekt von der gleichen Klasse wie das Ursprungsobjekt machen, weil folgendes:
Delphi-Quellcode:
var
  MeinObjekt: TEgal;
  MeineInstanz: TEgal;

...

MeinObjekt := TEgal.Create;
MeinObjekt.Wert := 10;

MeineInstanz := MeinObjekt;

FreeAndNil(MeinObjekt);
so und wenn ich jetzt folgendes mache:
Delphi-Quellcode:
WriteLn(IntToStr(MeineInstanz.Wert));
gibt es mir trotz, dass ich das Ursprungsobjekt mit FreeAndNil vernichtet habe immer noch den Wert 10 aus, wieso? An der Speicherstelle dürften doch keine Daten mehr sein. Und das ist meine Frage: wie mache ich eine eindeutige Instanz eines Objektes, mit welcher ich Prüfen kann ob das Ursprungsobjekt noch vorhanden ist? Ich weiss auch, dass ich testen kann ob MeinObjekt = nil ist, aber ich will das Objekt ja z.B einem Formular etc. übergeben welches nach der Übergabe die Variable MeinObjekt nicht mehr bekannt ist, sondern nur noch die Instanz, welche als Objektvariable des Formulars gespeichert ist, im Sinne von:
Delphi-Quellcode:
Form.UebergabeDesObjektes(MeinObjekt);
Danke, oder besser: :wiejetzt:

:)

Jens Schumann 11. Jan 2004 17:29

Re: Instanz eines Objektes auf existenz Prüfen
 
Hallo
Zitat:

Zitat von Skript
gibt es mir trotz, dass ich das Ursprungsobjekt mit FreeAndNil vernichtet habe immer noch den Wert 10 aus, wieso? An der Speicherstelle dürften doch keine Daten mehr sein.

Solange der Speicher nicht über schrieben wird steht da auch die 10. Nur weil ein Objekt freigegeben wird wird doch nicht der Arbeitsspeicher an der Stelle gelöscht.
Dein Problem ist, das Du ein Object erzeugst und in einer Variablen eine Referenz darauf speicherst.
Jetzt gibst Du mit FreeAndNil das Object frei. Die ObjektInstanz zeigt jetzt auf Nil.
Aber was ist mit der Variablen. Die zeigt immer noch auf den Speicherbereich.
Wenn Du unbedingt die Objektreferenz in einer extra Variablen speichern möchtest/musst, dann
musst Du die Variable explizit auf Nil setzen, wenn Du das Objekt freigibst.

Ich halte Dein Vorgehen für einen groben Designfehler. Überlege nochmal
ob das wirklich nötig ist. Siehe auch den Beitrag von Christian Seehase.

Skript 11. Jan 2004 18:20

Re: Instanz eines Objektes auf existenz Prüfen
 
Oh okay, das macht natürlich dann Sinn. Hmm, aber wenn du folgendes Scenario hast: Ich habe ein globales Objekt welches Daten enthält. Auf dieses Objekt greifen verschiedene Formulare zu, die einen lesen etwas daraus, die anderen schreiben etwas rein etc. Jetzt muss ich doch den Formularen sagen auf welches Objekt sie zugreifen müssen, also muss ich ihnen eine Instanz auf dieses Objekt übergeben. Wenn jetzt das Ursprungsobjekt gelöscht wird, muss das Formular, welches noch eine Instanz/Adresse enthält das merken? Es gibt natürlich da die Möglichkeit das Objekt als globale Variable zu definieren und alle greifen auf das selbige zu, nur wird bei mir das/die Objekt(e) dynamisch, also zur Laufzeit erstellt. Oder wie soll ich das machen? :wall:

Jelly 11. Jan 2004 19:10

Re: Instanz eines Objektes auf existenz Prüfen
 
Hallo,

anderes Bsp ist doch dem beschriebenem Problem ganz ähnlich. Bei Komponenten kannst du auch als Eigenschaften auf andere Komponenten referieren. Z.B. referiert TDatasource über die Dataset-Eigenschaft auf eine Tabelle oder Query. Wird jetzt die TQuery von der Form gelöscht, kriegst du, falls du nicht explizit darauf achtest, eine Speicherverletzung, wenn du dir den Wert von Dataset in deiner TDatasource Komponente ankuckst.

Bei dem genannten Bsp. kriegst du diese Schutzverletzung natürlich nicht, da diese sauber abgefangen wird. Schau dir mal in dem Kontext die Methode "Notification" an, welche in der Klasse TComponent definiert ist. In der Delphi Hilfe findest du dazu mehr, hier kurzer Auszug:

Zitat:

Zitat von Delphi
A component can, if needed, act on the notification that a component is being inserted or removed. For example, if a component has object fields or properties that contain references to other components, it can check the notifications of component removals and invalidate those references as needed.

Wie ich bereits in einem Eintrag vorher schrieb, ist es nötig daß du bei deiner Klassenerzeugung die Owner Klasse mitübergibst.

Gruß,
Tom

Christian Seehase 11. Jan 2004 23:40

Re: Instanz eines Objektes auf existenz Prüfen
 
Moin Skript,

in so einem Falle würde ich den Formularen kein Objekt übergeben, sondern ich würde das Objekt als Eigenschaft meines Hauptformulares für die anderen zur Verfügung stellen.
Dadurch habe ich nur eine einzige Variable die die Referenz auf das Objekt enthält, und kann dann auch diese gezielt auf Gültigkeit testen, und das von jeder Stelle aus, von der ich Zugriff auf das Hauptformular habe.

maximov 12. Jan 2004 00:29

Re: Instanz eines Objektes auf existenz Prüfen
 
Hi.

Ich wollte noch anmerken, dass du meistens 'referenz' und 'instanz' verwechselst! Die beziehung von objekten und deren pointer wird bei der korrekten verwendung, dieser ausdrücke, sehr viel eindeutiger :wink:

cu.

Skript 12. Jan 2004 05:16

Re: Instanz eines Objektes auf existenz Prüfen
 
Halllloo,

vielen Dank für eure Antworten, ich glaube so kann ich das Problem lösen (bzw. umgehen) :P trotzdem schade, dass es nicht möglich ist Instanzen (bzw. Referenzen) einfacher zu handhaben und notification tönt einleuchtend bei Formularen/Komponenten.

tja dann bis zum nächsten Problem... :-D

Skript

maximov 12. Jan 2004 10:27

Re: Instanz eines Objektes auf existenz Prüfen
 
Zitat:

Zitat von Skript
... und notification tönt einleuchtend bei Formularen/Komponenten.

Nicht nur bei Formularen/Komponenten, sondern bei allen komplexeren objektstrukturen, bei denen es diverse beziehungen untereinander gibt. Hat mich einige mühe gekostet dieses konzept in meine basis-klasse einzubauen, aber löst genau dieses problem wunderbar :-D

cu.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:53 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