AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Referenzen auf ungültige Objekte

Ein Thema von stahli · begonnen am 14. Mär 2011 · letzter Beitrag vom 2. Mär 2012
Antwort Antwort
Seite 4 von 6   « Erste     234 56   
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#31

AW: Referenzen auf ungültige Objekte

  Alt 18. Mär 2011, 23:06
Allerdings verstehe ich generell die Interfaces (noch) nicht wirklich.
Das Interface dient hier nur als Behelfslösung, da Records keinen Destructor haben. Klassen haben zwar einen, aber Objekte in Records werden nicht automatisch finalisiert (freigegeben). Interfaces hingegen werden hingegen finalisiert. Bei der Finalisierung wird, wenn der Referenzzähler 0 ist, das Objekt, das hinter dem Interface steht, automatisch freigegeben, also der Destruktor wird aufgerufen. Über diesen Umweg schaffe ich es, dass z.B. für lokale Variablen am Ende der Funktion ihr Eintrag aus der Referenzliste des referenzierten Objekts entfernt wird.

Es wird mit Deiner Lösung jedem Objekt eine Referenzliste hinzugefügt...

Mein Ansatz war eher, dass man normale Objekte verwendet und "der Compiler" auf Wunsch die Referenzen extern verwaltet und ggf. nilt (ohne dass die Objekte eine Referenzliste verwalten müssen).

Meine oben gezeigten Quelltextauszüge machen das ja so (zwar noch etwas ungeschickt und eingeschränkt aber gut funktionsfähig). Die Objekte müssen zur Laufzeit nicht verwalten, von dem sie referenziert werden.

Die Registrierung der Referenz könnte der Compiler vornehmen, sobald eine Objektvariable einer anderen zugewiesen wird.
Dazu könnte eine zentrale Referenzliste verwaltet werden.
Habe ich schon verstanden, allerdings müsste der Compiler intern auch pro Objekt eine Liste verwalten. Mit Compiler Magic wäre natürlich die ganze Sache eleganter lösbar, aber da das zur Zeit nicht geht, habe ich halt mal geschaut, wie man der Idee in der Praxis am nähesten kommen kann.

Dein Code ist aber beeindruckend (vielleicht verstehe ich den ja irgendwann )
Danke, Danke

[edit]
Übrigens, wenn ich keinen Denkfehler habe, müsste sich mein Code sogar so erweitern lassen, dass Objekte, auf die keine Referenz mehr existiert, automatisch zerstört werden (also so ähnlich wie Interfaces). Durchaus eine spannende Sache...
[/edit]

Geändert von Namenloser (18. Mär 2011 um 23:16 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#32

AW: Referenzen auf ungültige Objekte

  Alt 18. Mär 2011, 23:09
Ich halte die Idee, die Referenzen aufzulisten, für einen nicht unproblematischen Weg:
  • es gibt immer mindestens so viele Referenzen wie Objekte (Speicherlecks mal ausgeschlossen )
  • man stelle sich mal das Nilen der Referenzen in mehrenen Threads vor, da wäre sicher einiges zu beachten


Mein Vorschlag:

(Globale) Events anbieten, welches bei Erstellung und Freigabe eines Objekts aufgerufen werden und eine Referenz erhalten.

Mit Hilfe der Events könnte man dann (wenn man möchte) Listen von Objekten verwalten, um damit die Existenz von Objekten zu prüfen (oder andere coole Sachen machen).
Alle Anderen bekommen dann als Overhead nur, dass während der Erstellung und Freigabe von Objekten geprüft wird, ob die Events gesetzt sind. Das sollte doch im allgemeinen Speicherverwaltungstrubel untergehen

Intellekt ist das Verstehen von Wissen. Verstehen ist der wahre Pfad zu Einsicht. Einsicht ist der Schlüssel zu allem.

Geändert von BUG (18. Mär 2011 um 23:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#33

AW: Referenzen auf ungültige Objekte

  Alt 18. Mär 2011, 23:39
Es ist eine Weile her dass ich mit Interfaces experimentiert habe, hatte aber das von mir gewünschte Verhalten nur mit TInterfacedPersistent, welches für den vorgeschlagenen Ansatz freilich unbrauchbar ist.
Diese automatische Freigabe von Objekten nur weil der Compiler weiß dass ein Objekt nicht mehr benötigt wird, bzw. die Notwendigkeit Objekte dann doch manuell freigeben zu müssen weil die Referenzen global gehalten wurden und aus Events erreichbar waren ... hier dann den Überblick zu behalten was nicht freigegeben werden darf(oder kann) und was freigeben werden muss hat mir die Sache damals dermaßen verleidet, dass ich mich für virtuelle Implementierungen entschieden habe.
Sorry für OT, hat ja eigentlich mit dem Thema nicht wirklich etwas zu tun.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.224 Beiträge
 
Delphi 10.4 Sydney
 
#34

AW: Referenzen auf ungültige Objekte

  Alt 3. Nov 2011, 13:12
Ich wieder...

Meine Verfahrensweise war ja folgende:
Bei Freigabe eines Objektes untersuche ich alle anderen Objekte per RTTI, ob diese mit einer Objekteigenschaft mein Objekt referenzieren. Dann werden diese betreffenden Objekteigenschaft auf nil gesetzt und danach mein Objekt freigegeben.

Im Grunde funktioniert das (ich arbeite nicht mit Threads) absolut perfekt. ABER es ist extrem langsam.
Ein paar "Optimierungen" musste ich jetzt entfernen, so dass ich die Sache auch nicht beschleunigen kann.

Daher habe ich nun doch eine Observer-Lösung im Auge, möchte das aber auch soweit in meinem App-Framework automatisieren, dass ich nicht zu viel von Hand regeln muss.

Heute Abend schaue ich mir nochmal NamenLozers Lösung an. Vielleicht verstehe ich das ja wenn ich mein Delphi zur Hand habe (so rein theoretisch habe ich keine Chance) und vielleicht lässt sich das ja gut für mich nutzen.

Eine Frage mal grundsätzlich: WANN wird denn eigentlich genau der Referenzzähler eines Objektinterface erhöht und verringert? Macht das der Compiler, wenn ein Objekt an eine Methode übergeben bzw. wenn diese beendet wird und außerdem auch wenn man ObjA := ObjB schreibt? Und das Objekt wird (erst) bei Ref=0 (tatsächlich) freigegeben?
Irgendwie tue ich mich mit den Interfaces immer noch zu schwer...
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli ( 3. Nov 2011 um 13:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.592 Beiträge
 
Delphi 10.4 Sydney
 
#35

AW: Referenzen auf ungültige Objekte

  Alt 3. Nov 2011, 13:41
Objekte haben keinen Referenzzähler (standardmäßig), also macht Delphi da auch nichts, beim Kopieren/Freigeben der Objektreferenz.

Das Einzig umständliche ist, daß man interfaces noch "zusätzlich" erstellen/verwalten muß.
Es wäre ja zu schön, wenn man aus einem Objekt (automatisch) ein Interface generieren könnte.

(aber wenn ich mir das grad überlege ... ich glaub das wäre möglich ... muß ich mal sehn, hab eh vor zu versuchen endlich mal einen Precompiler ins Delphi reinzubekommen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu ( 3. Nov 2011 um 13:44 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
8.095 Beiträge
 
Delphi 10.4 Sydney
 
#36

AW: Referenzen auf ungültige Objekte

  Alt 3. Nov 2011, 13:45
WANN wird denn eigentlich genau der Referenzzähler eines Objektinterface erhöht und verringert?
Wenn die Variable aus dem Scope läuft (sprich Methodenende, Objektfreigabe des beinhaltenden Objekts, ...) oder einen anderen Wert zugewiesen bekommst, wird _Release aufgerufen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.592 Beiträge
 
Delphi 10.4 Sydney
 
#37

AW: Referenzen auf ungültige Objekte

  Alt 3. Nov 2011, 15:10
Aber nur bei einem "Interface", aber nicht bei Objekten (es sei denn ein Interface wurde angegeben und die eingebetteten Objekte werden über das Interface referenziert/angesprochen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.224 Beiträge
 
Delphi 10.4 Sydney
 
#38

AW: Referenzen auf ungültige Objekte

  Alt 3. Nov 2011, 16:04
Also ist es so?

Ich habe 3 Interfaces I1, I2, I3 und erzeuge "in jedes" ein Objekt (O1, O2, O3).

Alle Interfaces haben den Referenzzähler 1.

MyProcedure(I2) erhöht für I2 den Referenzzähler auf 2 bis die Prozedur verlassen wird.

I4 := I2 erhöht wieder für I2 den Referenzzähler auf 2?
I2.Free löst das objekt dann noch nicht auf.
Über I4 wäre es noch ansprechbar?

Aber was wäre wenn man I1 := I3 zuweist? O1 würde aufgelöst und I3 der Referenzzähler erhöht?

Die Objekte selbst sollten dann aber auf keinen Fall händisch aufgelöst werden (also auch nicht aus einer TObjectList mit OwnObjects entfernt werden).

Wenn es einem nicht darum geht, eine Art Mehrfachvererbung zu nutzen (unterschiedliche Objekte mit gleichen Methoden), sondern nur die Referenzierungen sinnvoll behandeln will, dann ist das schon recht kompliziert und aufwendig.

Meine Überlegung war: Wenn für Interfaces die Referenzen vom Compiler überwacht und verwaltet werden, dann sollte das grundsätzlich ja auch für normale Objekte möglich sein. Ok, die müssten noch eine Referenzliste o.ä. erhalten, aber dann würde das automatisiert im Hintergrund ablaufen können.
Philips Lösung sieht ja schon richtig gut aus (ich werde das heute Abend mal ansehen, auch in Bezug auf Objektreferenzen in Propertys). Wenn der Compiler so etwas aber nativ verwurschteln würde wäre m.E. eine der größten Schwächen von Delphi abgestellt. Projekte ließen sich viel leichter realisieren, da ALLE Zugriffe auf aufgelöste Objekte auf NIL zugreifen würden (statt auf zufällige Speicherstellen).
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.592 Beiträge
 
Delphi 10.4 Sydney
 
#39

AW: Referenzen auf ungültige Objekte

  Alt 3. Nov 2011, 19:08
Man kann Interfaces auch ohne Referenzzählung laufen lassen.
Dann muß man entweder noch Zugriff auf die Objektreferenz haben oder man baut sich eine "gib dich frei"-Methode mit ein, worüber man das Interface dann freigeben kann.
Aber da ist zu beachten, daß bei freigabe alle übrigen Referenzen, sollten noch welche vorhanden sein, zum Absturz führen können, wenn diese feigegeben werden und Delphi dem Interface (welches ja nicht mehr existiert) dieses mitteilen will.

PS: Deswegen speichert man sich manchmal auch als Pointer gecastete Interfacereferenzen, da dort keine automatische Referenzzählung auftritt.


Aber: Nimm dir besser eine TInterfaceList, in dieser hälst du dir eine Referenz und so immer Eine übrig ist, wird das Interface frühestens dann freigegeben, wenn diese InterfaceListe ebenfalls seine Referenzen freigibt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#40

AW: Referenzen auf ungültige Objekte

  Alt 3. Nov 2011, 20:28
@stahli:

Wenn ich dich richtig verstehe, dann willst du für deine Objekte das gleiche Verhalten wie in einer Datenbank bei ForeignKeys.
Die können z.B. bei einer Löschung des Basis-Datensatzes alle verlinkten Datensätze entsprechend aktualisieren und dort die Referenz z.B. auf NULL setzen.

Ein Ansatz dazu wäre folgender:

Delphi-Quellcode:
type
  TTurnier = class
  private
    fPersonID : integer;
    procedure SetPerson( const Value : IPerson );
    function GetPerson : IPerson;
  public
    property Person : IPerson read GetPerson write SetPerson;
  end;

procedure SetPerson( const Value : IPerson );
begin
  fPersonID := Value.ID;
end;

function GetPerson : IPerson;
begin
  Result := GlobaleObjektListe.GetPerson( fPersonID );
end;
Jetzt kannst du bei Bedarf die Person aus der Turnier-Instanz holen und bekommst nur dann eine gülitge Instanz, wenn es diese Person auch noch in der GlobalenObjektListe enthalten ist.

Diese GlobaleObjektListe gibt die Instanzen allerdings nicht frei, sondern vergisst diese einfach nur (IPerson => Interface).
Dann sollte es nicht mehr rumsen und die Referenzen sind sauber.

Und dieses Rumgeeiere mit RTTI kannst du dir sparen
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 +2. Es ist jetzt 01:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf