Autor Beitrag
matze
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Do 17.09.09 11:45 
Hallo.

Ich habe ein etwas blödes Problem:
In meiner Anwendung gibt es recht viele Objekte, die sich auch untereinander "verlinken". Jetzt kann es sein, dass ein Objekt gelöscht wird.
Wie kann ich denn in meinen anderen Objekten abfragen, ob es das Objekt, auf das ich gerade zugreifen will, noch gibt?
Das Feld mit dem Objekt kann ja nicht auf nil gesetzt werden, demzufolge fällt auch eine Überprüfung mit Assign aus oder?

Wie mache ich sowas denn also richtig?

Danke,
Matze

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Do 17.09.09 12:21 
user profile iconmatze hat folgendes geschrieben Zum zitierten Posting springen:
Das Feld mit dem Objekt kann ja nicht auf nil gesetzt werden, demzufolge fällt auch eine Überprüfung mit Assign aus oder?

Wieso kann das nicht auf nil gesetzt werden?
Gib die doch einfach mit FreeAndNil frei.
ausblenden Delphi-Quelltext
1:
FreeAndNil(FMyObject);					

_________________
PROGRAMMER: A device for converting coffee into software.
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Do 17.09.09 12:36 
Weil das Objekt nicht immer von dem Objekt gelöscht wird, das es auch benutzt.

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10184
Erhaltene Danke: 1259

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 17.09.09 12:50 
Moin!

Man kann grundsätzlich nicht rausfinden, ob ein Pointer auf "gültigen" Speicher zeigt (also ob da ein anderes Objekt "lebt"). Ansatz: Registriere alle Objekte in einer (klassen-)globalen Objekt-Liste, so dass diese auch der Eigentümer der Objekte ist. Wenn du ein Objekt freigibst, dann erledigst du das über diese globale Liste. Willst du prüfen, ob eine Referenz noch gültig ist, schaust du in der Objekt-Liste nach. :idea: Ist nicht unbedingt effizient, aber funktioniert. :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Do 17.09.09 13:18 
Ja das ginge auch.
Was passiert denn, wenn ich trotzdem auf das Objekt zugreife? Dann bekomme ich doch ne Access Violation oder? Aber die kann ich doch mit try except abfangen oder nicht?

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10184
Erhaltene Danke: 1259

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Do 17.09.09 13:22 
Moin!

user profile iconmatze hat folgendes geschrieben Zum zitierten Posting springen:
Was passiert denn, wenn ich trotzdem auf das Objekt zugreife? Dann bekomme ich doch ne Access Violation oder? Aber die kann ich doch mit try except abfangen oder nicht?
Nein, du kriegst nicht automatisch eine Exception. Bestenfalls liegen die Daten des Objekts noch an der Stelle im RAM, so dass der Zugriff zu klappen scheint, schlechtestenfalls sind die Daten überschrieben und du greift auf "nicht initialisierten" Speicher zu - was dabei passiert, ist nicht vorhersagbar. :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Do 17.09.09 13:44 
na klasse :-( dann bleibt also nur der Weg über eine Liste. Oder gibts da noch andere Möglichkeiten?

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 17.09.09 14:30 
Naja... du könntest eine Referenz-Zählung a la Interfaces bauen, statt direkt die Objekte freizugeben. Musst dann nur ab und zu mal garbage collecten (oder wie auch immer das Verb dazu heißt).

Ich mach das allerdings meistens so, dass sich die Objekte selbst merken, wer Referenzen auf sie hält. Beim Freigeben wandert dann eine Reihe von Notifications raus "Achtung, mich gibts gleich nicht mehr".
So ähnlich macht das ja auch die VCL.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Do 17.09.09 14:42 
und die Objekte, die Referenz auf das andere halten, müssen sich dann bei diesem Anmelden oder wie?
Und wie lässt du diese "Meldung" versenden?

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 17.09.09 15:59 
user profile iconmatze hat folgendes geschrieben Zum zitierten Posting springen:
und die Objekte, die Referenz auf das andere halten, müssen sich dann bei diesem Anmelden oder wie?

Jap.

Die Referenzen sind Properties einer Klasse, so dass sich der Setter drum kümmern kann bei der neuen an- und der alten abzumelden. Muss man nur dran Denken, beim Freigeben dieses Property auf nil zu setzen, sonst hat man das gleiche Problem nur anders rum ;)

user profile iconmatze hat folgendes geschrieben Zum zitierten Posting springen:
Und wie lässt du diese "Meldung" versenden?

Die VCL kennt unterhalb von TComponent dafür NotifyComponent & Konsorten, bei mir sind das einfach nur Aufrufe an eine protected deklarierte Methode ("RemoveReference(Ref: TReferredObject)").
Beim Freigeben eines Referenzierten Objekts kann man dann einfach die Liste durchgehen und diese Methode aufrufen.


Falls ich mich grad wieder verquer ausgedrückt hab, sag bescheid. Ich hack dann mal schnell eine Demo, wie ich das meine.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
matze Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Do 17.09.09 16:52 
Nee das kapier ich schon :-)
Hmmm... Dann werd ich mir das mal durch den Kopf gehen lassen.

Aber ich seh schon, dass ich ohne eine Liste nicht auskommen werde.

Danke an alle!
Matze

_________________
In the beginning was the word.
And the word was content-type: text/plain.