Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie Mehrfachfreigabe eines Objektes verhindern? (https://www.delphipraxis.net/148191-wie-mehrfachfreigabe-eines-objektes-verhindern.html)

TheMiller 24. Feb 2010 16:10


Wie Mehrfachfreigabe eines Objektes verhindern?
 
Hallo,

wieder ich ;)

Ich hab grad noch ein Problem mit der Freigabe von Objekten. Ich habe zwei Objekte, die beide eine Referenz zu einem dritten Objekt haben. Wenn ich nun Objekt1 freigebe, wird automatisch Objekt3 freigegeben. Das rührt von der ObjectList, die die Eigenschaft OwnsObjects auf "True" stehen hat.

Wenn ich nun das Objekt2 freigebe (auch eine ObjectList), will diese natürlich auch wieder Objekt3 freigeben und es knallt.

Meine Frage ist jetzt, ob ich dieses Freigabeverhalten durch eine Prüfung beeinflussen kann. Oder muss ich deswegen OwnsObjects auf "False" stellen?

Danke im Voraus

Bernhard Geyer 24. Feb 2010 16:17

Re: Wie Mehrfachfreigabe eines Objektes verhindern?
 
OwnerObject = False oder alles auf Interfaces umstellen

himitsu 24. Feb 2010 16:20

Re: Wie Mehrfachfreigabe eines Objektes verhindern?
 
Daraum darf immer nur einwas die Kontrolle über die Freigabe eines Objektes bestimmen.

Bei Interfaces und anderen Dingen mit Referenzzählung liegt die "Gewalt" Beim Object [3] selber, da es mitzählt, wie oft es verwendet wird.
(PS: sowas kann man auch für Objekte realisieren)

Problem hierbei wird sein, daß das eine Objekt [1], bzw. deren Objektlist [1] oder das freizugebende Objekt [3] nichts von dem anderen Objekt [2] und dessen Objektliste [2] weiß.
Wenn doch, dann muß das Objekt [3] dort aus einer der beiden Listen [1 oder 2] gelöscht werden.
- entweder aus Liste [1] ohne es [3] freizugeben
- oder aus Liste [2] anschließendem Freigeben, zusammen mit Liste [1]
- oder man implementiert eine Referenzzählung und läßt das Objekt [3] entscheiden
- oder man übergibt die Kontrolle einer weiteren Partei [4], welche weiß wo oder wie oft es [3] verwendet wird ... praktisch ähnlich der Referenzzählung

TheMiller 24. Feb 2010 16:22

Re: Wie Mehrfachfreigabe eines Objektes verhindern?
 
Mit Interfaces kenne ich mich noch nicht aus. Also kümmer ich mich selbst erstmal um die Freigabe, bis ich weis, was Interfaces sind, was sie können und wozu man sie konkret braucht. Ein bissl weis ich ja, aber zum Programmieren reicht's noch nicht.

Danke :thumb:

@himitsu: Vielen Dank für deinen ausführlichen Post. Ich werde sehen, wie ich meine Zwickmühle hier jetzt löse und mich dann mal um Interfaces kümmern. Danke

mjustin 24. Feb 2010 16:35

Re: Wie Mehrfachfreigabe eines Objektes verhindern?
 
Zitat:

Zitat von DJ-SPM
Wenn ich nun das Objekt2 freigebe (auch eine ObjectList), will diese natürlich auch wieder Objekt3 freigeben und es knallt

Einfache Daumenregel:

Zitat:

"wer Objekte erstellt, ist auch dafür zuständig, sie wieder freizugeben."
OwnsObjects=True ist nur dann sicher, wenn ein Objekt nicht gleichtzeitig in mehreren Listen mit OwnsObjects=True enthalten ist. Nicht sicher zu wissen, welche Objektliste ein Objekt besitzen und freigeben soll, würde schon in die Rubrik 'böser Designfehler' passen.

himitsu 24. Feb 2010 16:38

Re: Wie Mehrfachfreigabe eines Objektes verhindern?
 
Delphi-Quellcode:
type
  TReferenceObject = class
  private
    FReferences: Integer;
  public
    procedure FreeInstance; override;
    procedure IncRef;
    procedure DecRef;
  end;

procedure TReferenceObject.FreeInstance;
begin
  if FReferences = 0 then
    inherited FreeInstance;
end;

procedure TReferenceObject.IncRef;
begin
  Inc(FReferences);
end;

procedure TReferenceObject.DecRef;
begin
  Dec(FReferences);
end;
Allerdings muß man hier aufpassen, daß .IncRef und .DecRef ordentlich gesetzt und auch wieder zurückgesetzt werden, sonst bekommt man Probleme.
Delphi-Quellcode:
Obj := TObj.Create;
Obj.IncRef;

Obj2 := Obj;
Obj2.IncRef;

Obj.DecRef;
Obj.Free;

Obj2.DecRef;
Obj2.Free; // erst hier wird das Objekt freigegeben
Delphi-Quellcode:
Obj := TObj.Create;
Obj.IncRef;

Obj2 := Obj;
Obj2.IncRef;

Obj2.DecRef;
Obj2.Free;

Obj.DecRef;
Obj.Free; // erst hier wird das Objekt freigegeben
Bei Interfaces zählt Delphi aufomatisch mit und sorgt selber für's Freigeben, somit kann man sich nicht verzählen.

TheMiller 24. Feb 2010 16:49

Re: Wie Mehrfachfreigabe eines Objektes verhindern?
 
:shock:

Vielen Dank für den Quelltext. Das mit der Referenzzählung habe ich schon irgendwo mal gesehen. Naja, wie auch immer - um die Interfaces komm ich nicht drumrum - schon alleine, weil ich die irgendwie cool und professionell finde - daher: Lernen!

Aber erstmal setze ich dein Codebeispiel um.


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