![]() |
Überprüfen ob ein Objekt existiert aber wie?
Wie kann ich feststellen ob ein Bestimmtes Button oder TPanel existiert?? :gruebel:
Ich erstelle die Komponenten zur Laufzeit. Mein Problem ist das ich ein Panel.hide machen will --> aber wenn noch nicht erstellt --> Fehlermeldung |
Re: Überprüfen ob ein Objekt existiert aber wie?
hi,
Delphi-Quellcode:
Aenogym
if assigned(myButton) then
//existiert else //existiert nicht |
Re: Überprüfen ob ein Objekt existiert aber wie?
Objekte sind generell Pointer. Deshalb ist ein nicht erstelltes Objekt immer nil ;)
Einfach mit if Objekt <> nil oder ![]() |
Re: Überprüfen ob ein Objekt existiert aber wie?
Moin Dax,
Zitat:
Wenn das Objekt mit
Delphi-Quellcode:
freigegeben wird, oder lokal deklariert wird, stimmt die Aussage nicht, da dann der Pointer immer noch einen Wert enthält, aber nicht mehr (zumindest zwingend) auf das Objekt verweist.
Objekt.Free;
|
Re: Überprüfen ob ein Objekt existiert aber wie?
Zitat:
Du sprichst von einer Variable die eine Objektreferenz beinhaltet. Zitat:
Mit Assigned und/oder nil kannst du nur eine Variable prüfen, ob sie eine Objektreferenz beinhaltet oder halt nicht. Zitat:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var List: TStringList; begin if Assigned(List) then begin List.Add('So kann man nicht prüfen, ob ein Objekt existiert.'); List.Free; end; end; |
Re: Überprüfen ob ein Objekt existiert aber wie?
Vergesst, was ich gesagt habe :roll:
|
Re: Überprüfen ob ein Objekt existiert aber wie?
oha, okay. dann muss ich micha uch entschuldigen :roll:
Aenogym |
Re: Überprüfen ob ein Objekt existiert aber wie?
Vielleicht können die Beiträge im Thread
![]() |
Re: Überprüfen ob ein Objekt existiert aber wie?
Is zwar nich der beste Style aber funktionieren müsste das auch so:
Delphi-Quellcode:
denn das sollte in diesem Fall schon ausreichen oder?
try
Panel.hide except end; Greetz Boombuler |
AW: Überprüfen ob ein Objekt existiert aber wie?
Hallo Gemeinde,
ich greife dieses Thema nochmal auf, da ich irgendwie hier nicht weiterkomme: Ich möchte eine Art Toggle erstellen, der per Button ein Objekt erzeugt oder, wenn es schon vorhanden ist freigibt. Eigentlich ging ich davon aus, dass ich dies mit:
Delphi-Quellcode:
erreichen könnte. Jedoch bekomme ich schon beim 1. Aufruf im Else-Zweig eine Zugriffsverletzung. Dabei ist mir nur nicht ganz klar, warum Assigned schon beim 1. Prüfen das Objekt als erzeugt erkennt (?). Wo liegt hier mein Denkfehler?
var mPlayer:TMPlayer;
begin if not assigned(mPlayer) then mPlayer:=TMPlayer.create else freeandnil(mplayer); end; Danke für eure Hilfe!! |
AW: Überprüfen ob ein Objekt existiert aber wie?
Es ist beim 1.Mal einfach <> nil. Du solltest 'mPlayer' (und generell alle Variablen) initialisieren.
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Das ist eine lokale Variable, richtig? Die werden im Gegensatz zu globalen Variablen oder privaten Klassenfeldern nicht initialisiert, d.h. es steht irgendetwas drin, deshalb ist die Referenz nicht nil, obwohl das Objekt nicht existiert.
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Hallo zusammen,
danke für die Antworten.....ich blicke irgendwie nicht ganz durch: Meine Klasse TMPlayer (gekürzt):
Delphi-Quellcode:
Der Konstruktor wird auch erst aufgerufen, wenn ich das Objekt explizit erzeuge. Dies ist beim Start des Programmes nicht der Fall.
type
TMPlayer = class Private playlist:TStringlist; public constructor create(); // // destructor Destroy(); override; end; ?? |
AW: Überprüfen ob ein Objekt existiert aber wie?
Das hat aber doch mit der Variablen mPlayer nichts zu tun, die fragst Du doch ab.
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Schreib nochmal, was Du genau tun willst.
Die Klasse ist ja nur der Bauplan(Beschreibung) eines Objektes. Das Objekt muss dann noch erzeugt und einer Variablen zugewiesen werden.
Delphi-Quellcode:
Dabei wird der Constructor ausgeführt, der ja ansonsten einfach eine Methode ist.
Auto := TAuto.Create(Besitzer);
Dann kannst Du mit dem Auto arbeiten (fahren ;-) ). Ob die Variable Auto vorher nil ist oder irgendwelche zufälligen Daten darin stehen hängt davon ab, wo sie deklariert ist. Am sichersten einfach mal als erstes
Delphi-Quellcode:
zuweisen, sofern das Objekt nicht ohnehin gleich richtig erzeugt wird.
Auto := nil;
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Zur Verdeutlichung des eben Gesagten:
Delphi-Quellcode:
Der Compiler gibt für die lokale Variable auch eine entsprechende Warnung aus.
type
TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } FBla: TStringlist; //wird automatisch mit nil initialisiert public { Public-Deklarationen } end; ... procedure TForm1.Button1Click(Sender: TObject); var Bla: TStringlist; //wird NICHT initialisiert, enthält Zufallswert begin if Assigned(Bla) then ShowMessage('*Oops*, ein wilder Zeiger'); if Assigned(FBla) then ShowMessage('*Oops*, noch ein wilder Zeiger') else ShowMessage('Hier ist alles OK'); end; |
AW: Überprüfen ob ein Objekt existiert aber wie?
Hallo zusammen,
danke für eure Unterstützung. Vorhaben (ganz kurz): Ich schreibe gerade an einer Haussteuerung. Ein Hauptrechner (vermutl. ein Tablet), der div. Mikrocontroller im Haus via LAN ansteuert. Prinzipiell funktioniert das ganze schon recht gut. Nun möchte ich auch ein Webradio mit einbinden. Am Panel soll dieses aber separat an bzw. ausgeschaltet werden, da ich die Endstufen, die daran hängen gleich mit an bzw. ausschalte. Meine Idee war nun, mit dem Erzeugen des Objektes (mPlayer) aus der zugehörigen Klasse (TMplayer) die Controller anzusteuern. Im Konstruktor an, im Destruktor aus. Das ganze wird dann per Schalter im Programm realisiert. Folglich soll beim 1. Druck das ganze an und bei erneutem Drücken halt aus geschaltet werden. Dazu möchte ich prüfen, welchen Zustand das ganze hat und war der Meinung, dass ich dies idealerweise damit erledigen kann, indem ich prüfe, ob das Objekt erzeugt ist, oder eben nicht. Klasse:
Delphi-Quellcode:
Das Objekt:type TMPlayer = class Private playlist:TStringlist; public constructor create(); //Methoden / Eigenschaften destructor Destroy(); override; end;
Delphi-Quellcode:
Irgendwie zerstört ihr gerade meine Philosophie... :?
procedure TMainform.spSkinButtonMplayer3Click(Sender: TObject);
var mPlayer:TMPlayer; begin if not assigned(mPlayer) then mPlayer:=TMPlayer.create else freeandnil(mplayer); end; |
AW: Überprüfen ob ein Objekt existiert aber wie?
Zitat:
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Ahhh..dumm :wall: Danke!
Geändert....läuft...Tag gerettet! |
AW: Überprüfen ob ein Objekt existiert aber wie?
Wie gibst du das Objekt frei? Nur Free reich6t nicht. Du musst den Zeiger auf das Objekt auch auf nil setzen, damit die Überprüfung mit Assign funktioniert.
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Hallo Luckie,
Delphi-Quellcode:
freeandnil(mplayer)
Delphi-Quellcode:
Hoffe mal, das passt so..
destructor TMPlayer.destroy;
begin try // Abschalten + div Einstellungen zurücksetzen finally mplayer:=nil; inherited destroy; end; end; |
AW: Überprüfen ob ein Objekt existiert aber wie?
Eher nicht ...
Eine globale Variable ist schon mal pauschal pfui. Eine globale Variable innerhalb des
Delphi-Quellcode:
(so) auf
destructors
Delphi-Quellcode:
zu setzen ist der totale SuperGAU und daher immer falsch (selbst wenn es compiliert und anscheinend läuft).
nil
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Guten Morgen ;)
Wie wäre es dann besser? |
AW: Überprüfen ob ein Objekt existiert aber wie?
Delphi-Quellcode:
Und dort, wo Du die Objektinstanz freigibst, dann
destructor TMPlayer.destroy;
begin // Abschalten + div Einstellungen zurücksetzen inherited destroy; end;
Delphi-Quellcode:
FreeAndNil(mPlayer);
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Hallo DeddyH,
danke für die Antwort. Das Ganze hatte ich nach ein wenig drüber nachdenken schon geändert. Nun würde ich gern noch das "Eine globale Variable ist schon mal pauschal pfui" angehen. Ich hatte mir mal das Buch "Class in a box" gekauft. Dort ist das gängige Praxis, was ja nicht heißen muss, dass es "optimal" ist. Momentan habe ich die Variable im Interface-Abschnitt meines Hauptprogrammes deklariert:
Delphi-Quellcode:
Spricht da prinzipiell was dagegen?
unit Main;
interface uses // type TMainform = class(TForm) // // private // public // end; var Mainform: TMainform; mPlayer: TMPlayer; implementation //usw. Danke für eure Hilfe!! |
AW: Überprüfen ob ein Objekt existiert aber wie?
Damit hat jede Unit, die Main einbindet, uneingeschränkten Zugriff auf die Instanz. Willst Du das? Oder wäre es nicht besser, sie als privates Feld des Formulars zu deklarieren und den Zugriff nur über definierte Schnittstellen (wenn überhaupt) zu erlauben?
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Ein Singleton wäre hier noch eine Alternative. Eine Unit verwaltet Instantiierung, Zugriff und Freigabe. So etwa:
Delphi-Quellcode:
Der Zugriff erfolgt nur über die Funktion 'MediaPlayer', die bei Bedarf eine -und nur eine- Instanz erstellt.
Unit MPlayer;
interface function MediaPlayer : TMediaPlayer; implementation var _mediaPlayer : TMediaPlayer; _finalized : boolean; Function MediaPlayer : TMediaPlayer; Begin if _mediaPlayer=nil then if _finalized then Raise Exception.Create('Application has shut down.') else _mediaPlayer := TMediaPlayer.Create; result = _mediaPlayer; end; initialization _finalized := false; _mediaplayer := nil; finalization _finalized := true; FreeAndNil(_mediaplayer); end. Ich persönlich würde den Zugriff auf ein Gerät nicht in einem Formular kapseln, denn das ist dafür nicht zuständig. Das Gerät selbst muss wissen, ob es nur von einer Entität bedient werden kann oder ob es mit mehreren Anwendern klar kommt. |
AW: Überprüfen ob ein Objekt existiert aber wie?
Also speziell in diesem Fall mit dem MediaPlayer würde ich ein Facade Design Pattern wählen.
Mal vereinfacht angenommen, der MediaPlayer soll sich nachher bedienen lassen mit den Funktionen Play, Stop, Power (zum Ein-/Ausschalten), dann würde die Facade so aussehen:
Delphi-Quellcode:
Eine konkrete Facade wäre dann z.B.
IMediaPlayerFacade = interface
{GUID} procedure Play; procedure Stop; procedure Power; end;
Delphi-Quellcode:
Da der MediaPlayer aber nur eine Komponente von der Haussteuerung ist (nehme ich mal an), brauchen wir ein globales Steuerung-Element, wo alle anderen Facades gesammelt werden
TMediaPlayerFacade = class( TInterfacedObject, IMediaPlayerFacade )
private FPlayer : TMPlayer; protected procedure Play; procedure Stop; procedure Power; end; procedure TMediaPlayerFacade.Play; begin if Assigned( FPlayer ) then begin { Hier der Code um den Player zu starten } end; end; procedure TMediaPlayerFacade.Stop; begin if Assigned( FPlayer ) then begin { Hier der Code um den Player zu stoppen } end; end; procedure TMediaPlayerFacade.Power; begin if Assigned( FPlayer ) then begin FreeAndNil( FPlayer ); end else begin FPlayer := TMPlayer.Create; end; end;
Delphi-Quellcode:
Konkret kann das jetzt wie folgt umgesetzt werden
IHausSteuerung = interface
{GUID} function GetMediaPlayer : IMediaPlayerFacade; property MediaPlayer : IMediaPlayerFacade read GetMediaPlayer; end;
Delphi-Quellcode:
Der Lohn der Mühe ist dann die vereinfachte Benutzung der Module.
unit HausSteuerungSingleton;
interface uses HausSteuerungIntf; function HausSteuerung : IHausSteuerung; implementation uses MediaPlayerFacadeIntf, MediaPlayerFacade; var _HausSteuerung : IHausSteuerung; type THausSteuerung = class( TInterfacedObject, IHausSteuerung ) private FMediaPlayer : IMediaPlayerFacade; protected function GetMediaPlayer : IMediaPlayerFacade; public constructor Create; end; constructor THausSteuerung.Create; begin inherited; FMediaPlayer := TMediaPlayerFacade.Create; end; function THausSteuerung.GetMediaPlayer : IMediaPlayerFacade; begin Result := FMediaPlayer; end; function HausSteuerung : IHausSteuerung; begin if not Assigned( _HausSteuerung ) then _HausSteuerung := THausSteuerung.Create; Result := _HausSteuerung; end; 3 Button auf die Form geklatscht, die Unit
Delphi-Quellcode:
in die
HausSteuerungSingleton
Delphi-Quellcode:
Uses-Liste aufnehmen und die Button-OnClick Ereignisse jeweils mit
implementation
Delphi-Quellcode:
verdrahten
HausSteuerung.MediaPlayer.Power;
// bzw. HausSteuerung.MediaPlayer.PLay; // bzw. HausSteuerung.MediaPlayer.Stop; |
AW: Überprüfen ob ein Objekt existiert aber wie?
Hallo zusammen,
vielen Dank für die Ansätze/Vorschläge. Die letzten beiden werde ich mir wohl mal als "Bettlektüre" drucken müssen....(um sie zu verstehen ;) ) |
AW: Überprüfen ob ein Objekt existiert aber wie?
@Furtbichler
Kannst du mal bitte kurz erläutern, welchen Zweck dieser Bereich erfüllt, bzw. wann dieser aufgerufen wird?:
Delphi-Quellcode:
Danke euch allen!!!
initialization
_finalized := false; _mediaplayer := nil; finalization _finalized := true; FreeAndNil(_mediaplayer); end |
AW: Überprüfen ob ein Objekt existiert aber wie?
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Zitat:
Beim Starten der Anwendung werden alle 'Initialization'-Bereiche aller eingebundenen (explizit und implizit) Units aufgerufen: der richtige Ort, um Variablen zu initialisieren. Global ist 'böse' bzw. sollte vermieden werden, aber wer statische Klassen albern findet, kann hier in the old fashioned way seine statischen Felder initialisieren. Beim Beenden wird der 'Finalization'-Abschnitt aller Units aufgerufen. Hier kann man aufräumen. Ich initialisiere die Variable '_mediaplayer' mit nil. Beim ersten Aufruf der Funktion 'Mediaplayer' wird sie initialisiert. Aber nur dann, wenn der Finalization-Abschnitt noch nicht durchlaufen wurde. |
AW: Überprüfen ob ein Objekt existiert aber wie?
Danke euch beiden!
Werde mir das heute abend mal anschauen bzw. ausprobieren. |
AW: Überprüfen ob ein Objekt existiert aber wie?
Hier noch ein weiter Ansatz:
Delphi-Quellcode:
derMischka
function ObjectExists(aObj: TObject): boolean;
begin Result := False; if aObj = nil then exit; try Result := aObj.InheritsFrom(TObject); except end; end; |
AW: Überprüfen ob ein Objekt existiert aber wie?
Zitat:
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Zitat:
Aber das kaschiert ja nur den eigentlichen Fehler. Und *das* ist sogar noch schlimmer als leere exception-Blöcke. |
AW: Überprüfen ob ein Objekt existiert aber wie?
Das ganze Konstrukt ist böse. An der Stelle im Speicher kann ja gerade rein „zufällig“ was stehen, was so aussieht wie ein Objekt. Und ausgerechnet in dem Fall, dass das Objekt gerade freigegeben wurde, ist es sehr wahrscheinlich, dass die Daten noch 1:1 dort stehen, obwohl das Objekt theoretisch nicht mehr existiert (es sei denn, Delphi nullt den Speicherbereich nach der Freigabe, tut es aber soweit ich weiß nicht).
|
AW: Überprüfen ob ein Objekt existiert aber wie?
Wie böser kann man eigentlich werden, also böser als *Böse*? Nicht das das hier abfärbt und irgendwie ein Eigenleben entwickelt.
Nichtsdestotrotz: Richtiger Einwand. |
AW: Überprüfen ob ein Objekt existiert aber wie?
zu meiner Verteidigung:
Da das Ergebnis mit False oben initialisiert ist, braucht man die "nur lesende" Funktion in der Exception-Klammer ncht weiter behandeln --> es wurde kein Code verändert (da nur gelesen) und bei einer Exception ist das richtige Ergebnis (False) ja schon im Register eax. der Mischka |
AW: Überprüfen ob ein Objekt existiert aber wie?
Besser? Oder auch noch böse? ;-)
Delphi-Quellcode:
function ObjectExists(aObj: TObject): boolean;
begin Result := aObj <> nil; if Result then try Result := aObj.InheritsFrom(TObject); except Result := false; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz