![]() |
Wann is Class von TObject abgeleitet (FreeAndNil)
Hallo zusammen,
habe gerade festgestellt, dass meine Klasse nach FreeAndNil nicht sicher NIL ist. Ich habe dann in der Hilfe folgenden Hinweis gefunden: Zitat:
Delphi-Quellcode:
type
TTest = class private public constructor Create; destructor Destroy; override; end; |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Hmm, eigentlich sollte eine Objektvariable nach FreeAndNil(Obj) immer nil sein.
Es wird letztlich
Delphi-Quellcode:
und
Obj.Free;
Delphi-Quellcode:
durchgeführt.
Obj := nil;
Der Hinweis könnte m.E. so interpretiert werden, dass Obj ein Objekt sein muss. Ein Problem könnte sein, wenn im Destructor eine Expression auftritt. Zeig vielleicht mal Dein Ursprüngliches Problem. Vielleicht lässt sich das ja aufklären. |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
Ich halte es auch für zielführender, du würdest dein reales Problem zeigen. |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
Du schreibst eine Klasse. Davon kannst du Instanzen erzeugen (mit .Create()) und du speicherst Verweise (/Referenzen) auf diese Instanzen in Variablen. Diese Verweise können nil werden. Aber wenn ein Verweis nil wird, werden nicht alle Verweise auf die gleiche Instanz auch nil. Ich vermute, du machst sowas:
Delphi-Quellcode:
var a, b: TTest;
begin a = TTest.Create(); b := a; FreeAndNil(a); // Ergebnis: a = nil b = 0x56a4bf00 // Verweist noch auf die Adresse, darf nicht mehr zugegriffen werden |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Hoi, in so kurzer Zeit so viele Antworten. Corona machts möglich :-D
Bisher bin ich auch davon ausgegangen, dass bei keiner Angabe automatisch von TObject abgeleitet wird. Der explizite Hinweis in der Hilfe hat mich dann aber verunsichert. Wie könnte man denn dann eine Klasse erstellen, die nicht von TObject abgeleitet ist? Hier mein vereinfachtes Konstrukt
Delphi-Quellcode:
Ich hoffe das stellt das Konstrukt verständlich da
unit uTestClass;
interface type TTestClass= class private public constructor Create; destructor Destroy; override; end; var TestClass: TTestClass; implementation ... end. unit Test; interface type TTestForm = class(TForm); published procedure FormCreate(Sender: TObject); private public constructor Create; destructor Destroy; override; procedure TuWas; end; var TestClass: TTestClass; implementation procedure TTestForm.TuWas; // Wird bei bestimmtem ProzessStand von Timer immer wieder aufgerufen begin ... if not TestForm.TestClassReady then // Wenn noch nicht gestartet oder noch nicht fertig begin if TestClass = nil then TestClass := TTestClass.Create; if not TestClass.TuWasAnderesReady then begin TestClass.TuWasAnderes; Exit; end else begin TestForm.TestClassReady := true; FreeAndNil(TestClass); end; end; ... end. Wenn ich nun TTestForm beende und für einen zweiten Lauf TTestForm.Create neu erzeuge ist beim zweiten Durchlauf TestClass.TuWasAnderesReady = True Das wird bei TTestClass.Create auf false gesetzt Beim zweiten Aufruf wird TTestClass.Create aber gar nbicht aufgerufen weil nicht Nil Ich prüfe aber noch mal, ob der Fehler sich anderst einschleicht |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Eben. Und damit ist der Hinweis sinnfrei.
Ich schau woher das Problem kommt. Wollte das nur grundsätzlich wissen. Aber eine Frage hätte ich doch noch zu dem Thema. Stimmt es, dass alleine mit der Zuweisung
Delphi-Quellcode:
auch der Speicher frei gegeben wird?
TestClass := nil;
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Nein. Das ist nur dann der Fall, wenn die Klasse ein Interface mit Referenzzählung implementiert (z.B. TInterfacedObject), über eben dieses Interface angesprochen wird und die letzte Referenz auf nil gesetzt wird. Ansonsten baust Du Dir mit der nil-Zuweisung ein Speicherleck, sofern keine andere Referenz auf die Instanz mehr existiert.
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
![]() |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Alles klar und vielen Dank.
Meine Fragen sind ausreichend beantwortet. |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Die haben bei mir den Weg von GoTo und With genommen, d.h. in meinem Wortschatz existieren sie nicht :mrgreen:
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
GoTo ist klar. Aber was spricht gegen With?
Ausser dass man dann im Code nicht gleich sieht, wo das Property/Object her kommt. Gibt es noch andere Gründe? PS: Mein Problem ist auch gefunden. Er ist nie in die FreeAndNil-Zeile gekommen :oops: |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
In etwas neueren Delphis, wenn für Nextgen mit ARC kompiliert, dort gibt es Weak-Referenzen, die automatisch auf NIL gesetzt werden, wenn das Objekt freigegeben wird.
Erstmal werden beim ARC die Referenzen gezählt und das Objekt die Instanz des Objektes wird erst freigegeben, wenn alle Variablen weg sind. Free, FreeAndNil und Destroy machen dort absolut garnichts (ja, das ist ein extrem blödes Verhalten und der Mist mit dem DisposeOf ist schwachsinn) Jedenfalls gibt es dort das Attribut
Delphi-Quellcode:
, was auch extrem krank ist, denn das Attribut kann man auch bei Nicht-ARC angeben, aber es wird dort ohne Fehlermeldung einfach still und heimlich ignoriert. (ja, ich würde den Erfinder gern mal grün nd blau hauen, aber so richtig)
[Weak]
Delphi-Quellcode:
{$IFNDEF AUTOREFCOUNT} {MESSAGE Fatal 'du kommst hier net rein'} {$ENDIF}
var x, y: TObjekt; [Weak] z: TObjekt; x := TObject.Create; y := x; // diese Referenz wird gezählt z := x; // diese Weak-Referenz wird nicht gezählt und automatisch NIL if z = nil then ; // nee x := nil; // das automatische x.Free, aber da Y noch existiert y := nil; // jetzt wirklich das automatische Free und Z wird genilt if z = nil then ; // jupp, ist auch weg Im Prinzip bekommt die Objektinstanz hier eine Adress-Liste wo alle Weak-Referenzen liegen und beim Destroy werden sie auf NIL gesetzt. Bei ARC muß man extrem aufpassen keine Kreisreferenzen zu bekommen
Delphi-Quellcode:
Ohne WEAK würden im ARC sich die beiden Instanzen gegenseitig halten, selbst wenn es extren keine Referenzen/Variablen mehr gibt.
type
TChild = class; TOwner = class FChild: TChild; // oder gat viele Childs end; TChild = class [Weak] FTOwner: TOwner; end; Im Prinzip arbeiten alle Objekte dort wie Interfaces. |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
2. Manchmal soll es auch vorkommen, dass der Compiler da was verwechselt. Da ich with aus dem ersten Grunde schon nicht verwende, habe ich keine praktischen Erfahrungen mit dem zweiten Phänomen. |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
Zitat:
Delphi-Quellcode:
var R: TRect;
with R do {Self.}Width := {R.}Right - {R.}Left; // was der Entwickler sich dachte und wie es früher war {with R do} R.Width := R.Right - R.Left; // Was Delphi jetzt macht, seitem TRect mit einem Helper verbessert wurde {Self.}Width := R.Width; // und was man jetzt auch machen kann |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
SCNR ;-) |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Nichts?
IF ist ein oder zwei versteckte GOTO, CASE ist mehrere GOTO, WHILE und REPEAT sind GOTO, ... (bzw. alle sind JUMPs) Und WITH ist auch nur eine unsichtbare temporäre Variable, der man leider nicht ansieht, wo die nun alles dranhängt. |
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
|
AW: Wann is Class von TObject abgeleitet (FreeAndNil)
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz