![]() |
TNotification DisposeOf oder Free?
Hallo
in den Beispielen bei Embarcadero ![]() Wird mal Free und ein anderes mal DisposeOf verwendet. Kann mit jemand den Unterscheid erklären? Ciao Stefan |
AW: TNotification DisposeOf oder Free?
In Non-ARC Umbegungen ist
Delphi-Quellcode:
identisch zu
DisposeOf
Delphi-Quellcode:
.
Free
Bei den ARC-Compilern wird bei
Delphi-Quellcode:
zwar der Destructor-Code durchlaufen, aber die Instanz wird noch nicht freigegeben (das erledigt dort ja das ARC). Damit bleiben Referenzen auf die Instanz weiterhin gültig, obwohl das Objekt nicht mehr voll arbeitsfähig ist. Über
DisposeOf
Delphi-Quellcode:
kann man diesen Zustand abprüfen.
Disposed
|
AW: TNotification DisposeOf oder Free?
Als Ergänzung zu Uwe
DisposeOf sollte man meiner Meinung nach nur dann verwenden wenn:
|
AW: TNotification DisposeOf oder Free?
Zeitgleich muss man natürlich auch aufpassen das Objekt nach einem
Delphi-Quellcode:
nicht mehr anzufassen. "Nicht mehr voll arbeitsfähig" finde ich da sehr harmlos umschrieben. Im Endeffekt ist das nicht mehr viel anders als ein dangling Pointer.
DisposeOf
|
AW: TNotification DisposeOf oder Free?
Ein dangling pointer ist etwas gänzlich anderes und hat auch noch seine ganz eigenen Tücken.
NON-ARC (dangling pointer) Ich habe irgendwo eine Referenz auf eine Instanz vom Typ TFoo. An irgendeiner Stelle im Programm wird diese Instanz freigeben. Jeder Zugriff auf diese Instanz würde jetzt eine Exception produzieren. Aber, wenn im wieteren Verlauf der Anwendung eine Instanz erzeugt wird, die vom Typ TFoo oder Ableitung ist oder in der VMT an der gleiche Stelle eine Methode mit der gleichen Signatur besitzt und man verwendet jetzt diese alte TFoo Instanz (die, die eigentlich entsorgt wurde), dann gibt es keine Exception (obwohl es eine geben müsste). Es gibt also ein Szenario, wo es keine Exception gibt, obwohl es eine bräuchte. ARC Dieses oben skizzierte Szenario gibt es bei ARC nicht. Nach einem DisposeOf wird zuverlässig eine Exception geworfen, garantiert. |
AW: TNotification DisposeOf oder Free?
Wieder was gelernt.
Aber ist das mit den exakt passenden Methoden nicht ziemlich unwahrscheinlich? Der mMn interessantere Fall wäre: Hilft einem ARC weiter wenn man z.B. nur ein Feld einer toten Instanz beschreiben wollte? Wenn ich nicht komplett daneben liege würde unter Nicht-ARC dann halt Speicher beschrieben werden und mit Pech zerstöre ich mir hier etwas anderes. Wird das unter ARC verhindert wenn der Zeiger dereferenziert wird? |
AW: TNotification DisposeOf oder Free?
Der einzige Richtige Weg ist zu prüfen ob das Ding noch lebt. Also mit if not class.Disposed
Alles andere ist Murks!!! Deshalb nur mit klarem Design und klaren Besitzverhältnissen!! Meiner Meinung nach: Wenn nicht klar ist, wann erzeugt und zerstört wird ist das Design Schrott! |
AW: TNotification DisposeOf oder Free?
Delphi-Quellcode:
if Assigned(obj) {$IFDEF AUTOREFCOUNT}and not obj.Disposed{$ENDIF} then
Und .Free hat im ARC absolut keinerlei Funktion. Echt toll, dass man so plattformunabhängigen Code fast nicht mehr schreiben kann, ohne massig IFDEFs. Zitat:
.Free und früher war das Objekt mal weg ... jetzt ... nja, mal so und mal so.
Delphi-Quellcode:
var [WEAK] variable: type;
In aktuellen Delphis kann das nun endlich auch Windows. Aber alte Delphis sagen keinen Muggs. Mein Kollege war grade erst drauf reingefallen, dass XE sowas bei IInterface zulässt, aber es still und heimlich ignoriert, da der Compiler keine Warnung wirft, wenn er auf ihm unbekannte Attribute trifft. |
AW: TNotification DisposeOf oder Free?
Zitat:
Zitat:
|
AW: TNotification DisposeOf oder Free?
Zitat:
Delphi-Quellcode:
type
TObjectHelper = class helper for TObject function IsValid: Boolean; end; function TObjectHelper.IsValid: Boolean; begin Result := Assigned(Self); {$IFDEF AUTOREFCOUNT} if Result then Result := not Disposed; {$ENDIF} end; oder eine gleichwertige Hilfsfunktion:
Delphi-Quellcode:
function InstanceIsValid(Instance: TObject): Boolean;
begin Result := Assigned(Instance); {$IFDEF AUTOREFCOUNT} if Result then Result := not Instance.Disposed; {$ENDIF} end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:21 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-2025 by Thomas Breitkreuz