AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Freigabe von Objekten (Observerpattern)

Ein Thema von TheGroudonx · begonnen am 21. Mai 2014 · letzter Beitrag vom 11. Jun 2014
Antwort Antwort
TheGroudonx

Registriert seit: 21. Mai 2014
44 Beiträge
 
#1

Freigabe von Objekten (Observerpattern)

  Alt 21. Mai 2014, 12:46
Hallo,

ich habe folgendes Problem:

Infos:

Ich besitze ein ObjektX mit der Vererbung class(TInterfacedObject, IInterfaceX).
Dessen Referenz übergebe ich an ein normales Objekt.
Dieses normale Objekt meldet nun über das Interface Veränderungen an das ObjektX.

Problem:

Wenn das normale Objekt(befindet sich in einem Array) mit .free /.freeandnil / .destroy freigegeben wird,
wird das ObjektX scheinbar mitgelöscht, wodurch es beim Erstellen eines neuen
normales Objekts zu einer Zugriffsverletzung kommt. Ich konnte bisher etwas bezüglich eines Referenzzählers herrausfinden,
jedoch nicht wie die automatische Löschung umgehbar ist. Bisher bin ich deswegen gezwungen, auf .free zu verzichten.

Wenn ihr hilfreiche Tipps habt lasst es mich wissen
  Mit Zitat antworten Zitat
Namenloser

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

AW: Freigabe von Objekten (Observerpattern)

  Alt 21. Mai 2014, 13:03
Willkommen in der DP
Zitat:
Wenn das normale Objekt(befindet sich in einem Array) mit .free /.freeandnil / .destroy freigegeben wird,
wird das ObjektX scheinbar mitgelöscht, wodurch es beim Erstellen eines neuen
normales Objekts zu einer Zugriffsverletzung kommt.
Den Abschnitt verstehe ich nicht ganz. Was ist das „Objekt“, und was ist das „ObjektX“? Ist beides das gleiche Objekt, sind es unterschiedliche Objekte? Wo wird was „mitgelöscht“ und was heißt hier „scheinbar“?

Grundsätzlich kann man die automatische Freigabe eines Objektes hinter einem Interface verhindern, indem man manuell seine Methode AddRef aufruft. Dadurch wird der Referenzzähler um 1 erhöht und somit nicht 0 (was eine Zerstörung des Objekts auslösen würde), nachdem das letzte Interface gelöscht wurde.

Aber, meine Empfehlung: Wenn Interfaces, dann konsequent. Nicht Interfaces mit normalem Objektzugriff mischen. Das macht nur Kopfschmerzen. Also stell lieber die Stellen, wo du noch direkt auf das Objekt zugreifst, auch auf Interfaces um, dann hast du das Problem nicht und die Referenzzählung erledigt alles automatisch (nur bei zyklischen Referenzen musst du aufpassen).
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.008 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Freigabe von Objekten (Observerpattern)

  Alt 21. Mai 2014, 15:02
Ich besitze ein ObjektX mit der Vererbung class(TInterfacedObject, IInterfaceX).
Dessen Referenz übergebe ich an ein normales Objekt.

...


Wenn das normale Objekt freigegeben wird, wird das ObjektX scheinbar mitgelöscht, wodurch es beim Erstellen eines neuen
normales Objekts zu einer Zugriffsverletzung kommt.
Speicherst du dein ObjectX als Objektvariable oder als Interfacevariable? Im ersten Fall hast du also nicht die Referenzzählung getriggert, so dass dein Objekt, das du es als Interface übergibst die einige gezählte Referenz hält, wirds freigegeben, tickert der RefCount auf 0 und dein ObjectX wird freigegeben.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  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
 
#4

AW: Freigabe von Objekten (Observerpattern)

  Alt 21. Mai 2014, 16:46
Hier mal veranschaulicht
Delphi-Quellcode:
type
  IObjectX = interface
  end;

  TObjectX = class( TInterfacedObject, IObjectX )
  end;

procedure Test;
var
  LObj : TObjectX;
  LIntf : IObjectX;
begin
  LObj := TObjectX.Create; // RefCount ist 0
  LIntf := LObj; // RefCount+1 -> 1
  LIntf := nil; // RefCount-1 -> 0 -> Instanz wird freigegeben
  LObj.Free; // rumms, ist ja nix mehr da an der Referenz
end;
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
TheGroudonx

Registriert seit: 21. Mai 2014
44 Beiträge
 
#5

AW: Freigabe von Objekten (Observerpattern)

  Alt 22. Mai 2014, 15:55
Danke erstmal,

der genauere Code ist in 4 Units eingeteilt.

Hauptunit beinhaltet das ObjektX und das ObjektN
Die Unit von ObjektN speichert die Referenz auf das ObjektX als Interface


UHaupt:
ObjektN: Array of TObjektN;
ObjektX: TObjektX;

Code der Zugriffsverletzung verursacht:
ObjektN[x] := TObjektN.create(ObjektX);
ObjektN[x].freeandnil;
ObjektN[x] := TObjektN.create(ObjektX); <==



UObjektX:
TObjektX = class(TInterfacedObject, IObserverObjektX)



UObjektN:
TObjektN = class
var
ObjektX: IObserverObjektX;


UObserverObjektX
IObserverObjektX = Interface(IInterface)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#6

AW: Freigabe von Objekten (Observerpattern)

  Alt 22. Mai 2014, 16:01
Entweder nur mit der Instanz oder nur mit dem Interfacezeiger arbeiten. *NIE* nicht niemals kombiniert. Warum, hat seine Durchlaucht Rufo schon wunderbar erklärt.
  Mit Zitat antworten Zitat
TheGroudonx

Registriert seit: 21. Mai 2014
44 Beiträge
 
#7

AW: Freigabe von Objekten (Observerpattern)

  Alt 11. Jun 2014, 09:36
Danke für die Antworten.

Ich habe das Problem jetzt so gelöst, dass ich eine weitere Variable des Interfaces gespeichert habe, wodurch der Referenzzähler nichtmehr auf 0 geht, wenn ein Objekt gefreet wird, welches eine Interface-Referenz gespeichert hat.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.097 Beiträge
 
Delphi 12 Athens
 
#8

AW: Freigabe von Objekten (Observerpattern)

  Alt 11. Jun 2014, 09:51
Man kann natürlich auch mit Intf._AddRef rumspielen, oder die Referenzzählung direkt beeinflussen.

Siehe TComponent, welches Interfaces ohne Referenzzählung implementiert, wobei die Freigabe der Instanz also standardmäßig weiterhin ausschließlich über den Owner und .Free geregelt wird, oder eventuell auch über eingebettete VCL-Interfaces, welche die Kontrolle übernehmen.




Aber Grundsätzlich ist dein Vorgehen eher "falsch".

Entweder du nutzt das Objekt als Objekt und verwendest keine Interfaces, oder du nutzt das Objekt ausschließlich nur noch über Interface-Referenzen und schon gibt es keine Probleme damit.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  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
 
#9

AW: Freigabe von Objekten (Observerpattern)

  Alt 11. Jun 2014, 13:59
Delphi-Referenz durchsuchenTInterfacedPersistent ist schon eine Implementierung ohne Referenzzählung.
Ist halt nur doof, wenn man die Instanz freigibt und irgendjemand hat da noch die Finger drauf
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 +1. Es ist jetzt 07:10 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