Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Frage zu Interfaces (https://www.delphipraxis.net/130102-frage-zu-interfaces.html)

guidok 3. Mär 2009 14:52


Frage zu Interfaces
 
Ich habe noch ein wenig Probleme mit der Handhabung von Interfaces. Der nachfolgende Quellcode stammt aus dem Beispiel von OmniXML. Hier wird ein XMLDoc (was ja ein Interface ist) erzeugt, eine Datei erstellt, gespeichert und Schluss. Freigeben muss man XMLDoc offensichtlich nicht.

Wer gibt XMLDoc, wann frei?

Delphi-Quellcode:
var
  XMLDoc: IXMLDocument;

begin
  XMLDoc := CreateXMLDoc;
  XMLDoc.DocumentElement := XMLDoc.CreateElement('root');
  XMLDoc.DocumentElement.SetAttribute('attr', 'value');
  XMLDoc.Save('document.xml');
end.

xaromz 3. Mär 2009 14:56

Re: Frage zu Interfaces
 
Hallo,

Interfaces benutzen intern eine Referenzzählung, um sich selbst zu verwalten und zu zerstören:
Delphi-Quellcode:
var
  XMLDoc: IXMLDocument;

begin
  XMLDoc := CreateXMLDoc; // 1 Referenz -> Zähler = 1
  XMLDoc.DocumentElement := XMLDoc.CreateElement('root');
  XMLDoc.DocumentElement.SetAttribute('attr', 'value');
  XMLDoc.Save('document.xml');
end. // Keine Referenz mehr -> Zähler = 0 -> Objekt wird zerstört
Gruß
xaromz

guidok 3. Mär 2009 14:59

Re: Frage zu Interfaces
 
Was bedeutet "Keine Referenz mehr"?

Sprich: Wird das Objekt immer am Ende der Prozedur zerstört?

Ich benötige an anderer Stelle ebenfalls Zugriff auf das besagte XMLDoc und möchte daher etwas in dieser Art machen:

Delphi-Quellcode:
type
  TTest = class(TObject)
  private
    FXMLDoc: IXMLDocument;
  public
    procedure ErstelleRoot;
    procedure WeitereKnoten;
  end;

procedure TTest.ErstelleRoot;
begin
  FXMLDoc := CreateXMLDoc;
  FXMLDoc.DocumentElement := FXMLDoc.CreateElement('root');
end;

procedure TTest.WeitereKnoten;
  var
    WeitererKnoten: IXMLElement;
begin
  WeitererKnoten := FXMLDoc.CreateElement('Weiterer Knoten');
  FXMLDoc.DocumentElement.AppendChild(WeitererKnoten);
end;
Wann würde das Objekt in diesem Fall zerstört?

himitsu 3. Mär 2009 15:00

Re: Frage zu Interfaces
 
das Interface zählt praktisch mit, in wievielen Variablen ala "irgendwas: {InterfaceTyp}" es gespeichert ist und sobald es von keiner Variable mehr verwendet wird, zerstört es sich selber.

Delphi erhöht/erniedrigt diesen Zähler jedes mal, du z.B. ein Interface einer anderen Variable zuweißt ":=" oder wenn du Variablen gelöscht werden (z.B. am Ende einer Prozedur)



[add]
Zitat:

Was bedeutet "Keine Referenz mehr"?
wenn es keine Variable mehr gibt, vorin das Interface gepseichert wurde, bzw. wenn es aus den Variablen gelöscht wurde (XMLDoc := nil).

Zitat:

Wann würde das Objekt in diesem Fall zerstört?
wenn du die Instanz TTest freigibst und es sonst keiner Referenzen mehr gibt

guidok 3. Mär 2009 16:15

Re: Frage zu Interfaces
 
Ah so ist das. Danke für die Info.

Wie ist es, wenn ich die Prozedur aus dem o.g. Beispiel mehrfach aufrufen muss? Sollte ich sinnvollerweise das Interface vorher auf nil setzen?

Delphi-Quellcode:
procedure TTest.ErstelleRoot;
begin
  FXMLDoc := nil; //Interface löschen
  FXMLDoc := CreateXMLDoc;
  FXMLDoc.DocumentElement := FXMLDoc.CreateElement('root');
end;

himitsu 3. Mär 2009 16:19

Re: Frage zu Interfaces
 
mußt du nicht, bei jedem Aufruf wird ja die interface-Variable neu initialisiert und am Ende freigegeben

sirius 3. Mär 2009 18:20

Re: Frage zu Interfaces
 
Zitat:

Zitat von himitsu
mußt du nicht, bei jedem Aufruf wird ja die interface-Variable neu initialisiert und am Ende freigegeben

Er Hat jetzt das Interface als Feld einer Klasse deklariert und nicht mehr als lokale Variable.
Dadurch ist natürlich FXMLDoc u.U. noch gültig. Man braucht es deswegen aber nicht explizit auf nil setzen. Das macht Delphi automatisch für dich.

himitsu 3. Mär 2009 18:43

Re: Frage zu Interfaces
 
wenn er ein neues Interface erstellt (CreateXMLDoc), dann wird das alte aus dieser Variable freigegeben und würde sich demnach auch löschen

mjustin 4. Mär 2009 13:56

Re: Frage zu Interfaces
 
Zitat:

Zitat von himitsu
wenn er ein neues Interface erstellt (CreateXMLDoc), dann wird das alte aus dieser Variable freigegeben und würde sich demnach auch löschen

Nur wenn es keine anderen Referenzen gibt. Ich würde die Erzeugung z.B. in den Konstruktor verlegen, oder in eine Init-Methode, die vor der Verwendung des XMLDocuments aufgerufen werden muss.

himitsu 4. Mär 2009 14:01

Re: Frage zu Interfaces
 
Zitat:

Zitat von mjustin
Nur wenn es keine anderen Referenzen gibt. Ich würde die Erzeugung z.B. in den Konstruktor verlegen, oder in eine Init-Methode, die vor der Verwendung des XMLDocuments aufgerufen werden muss.

wenn es noch andere Referenzen gäbe, dann sollte es natürlich auch nicht freigegeben werden.
Aber die Referenz in dieser Variable würde dennoch freigegeben.


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