![]() |
Weak Referenzen überlegungen...
Hallo Zusammen...
Vor ARC haben wir uns keine sorgen gemacht, oder? Es wurde eine Objekt erzeugt und wenn wir es nicht mehr gebraucht haben, wurde einfach ein Free aufgerufen. Dann wurden wir plötzlich entmündigt und ein Free machte nix mehr... Besonders Fatal bei Sourcecode wo wir uns darauf verlassen haben, dass ein Free auch Freeed...:stupid:
Delphi-Quellcode:
Selbst so simpler Code schließt nicht mehr das Fester, weil komischerweise die Referent nach einem Create nicht 1 ist.
MyForm := TMyForm.Create;
try MyForm.Showmodal; finally MyForm.Free; end; Spätestens das dieser Stelle muss also ein Disposeof her. Also folgende Procedure geschrieben...
Delphi-Quellcode:
ARC hat sicherlich seine Vorteile, aber eigentlich nur, in Hinblick auf die CrossPlattform Programmierung, wenn uns ARC
Procedure ArcFree(Var Obj);
{$IF not Defined(AUTOREFCOUNT)} var Temp: TObject; begin Temp := TObject(Obj); Pointer(Obj) := nil; Temp.Free; end; {$ELSE} begin if Pointer(Obj) <> NIL then begin TFMXObject(Obj).Release; TFMXObject(Obj).DisposeOf; end; TObject(Obj) := nil; end; {$ENDIF} @EMBT - BITTE PER COMPILER-SCHALTER!!! auch unter Windows zur Verfügung steht. Jetzt habe ich eine [Weak] Referenz und speichere diese an 10000 Stellen in Listen usw. Wenn dann dieses Object geFreeed wird, müssen alle Pointer aus der Liste auf NIL gesetzt werden. Warum den nicht so arbeiten wir früher und immer ein ArcFree aufrufen? Keine Weak-Liste die Speicher verbraucht, keine Performance Einbußen bei einem Free, Fester gehen wirklich zu und mein Code läuft auch ohne ARC-Überlegungen. Ich rede hier nicht von neuem Code...!8-) Wenn man etwas neu programmiert, kann man sicherlich die Unterschiede - mal eben :wall: - berücksichtigen. Grüsse und einen schönen 2. Weihnachtsfeiertag wünscht Mavarik |
AW: Weak Referenzen überlegungen...
Also der Code
Delphi-Quellcode:
funktioniert unter ARC genauso wie unter Nicht-ARC. Der einzige Unterschied ist, dass die Form-Instanz unter ARC noch da ist. Macht aber erstmal nix, denn geschlossen wurde die, denn
MyForm := TMyForm.Create;
try MyForm.Showmodal; finally MyForm.Free; end;
Delphi-Quellcode:
kehrt erst dann zurück, wenn die Form geschlossen wurde.
ShowModal
(Ich lasse jetzt mal ausser Acht, dass ARC nur auf den Mobile-Plattformen läuft und dort dieser Code gar nicht funktioniert, weil es dort kein blockierendes
Delphi-Quellcode:
gibt.)
ShowModal
Nehmen wir also mal an, der Code ist so vorhanden:
Delphi-Quellcode:
dann ist das Verhalten exakt gleich. Nach dem Verlassen der Prozedur/Methode ist die erzeugte Form-Instanz aus dem Speicher verschwunden.
procedure Foo;
var MyForm : TMyForm; begin MyForm := TMyForm.Create; try MyForm.Showmodal; finally MyForm.Free; end; end;
Delphi-Quellcode:
Und jetzt? Wiederum eine identische Aussenwirkung. Eine neue Form-Instanz wird erzeugt, angezeigt und nach dem Schliessen wird die Methode verlassen. Einziger Unterschied auf ARC bleibt die Instanz bis zum erneuten Aufruf der Methode noch im Speicher.
TFoo = class
private MyForm : TMyForm; public procedure ShowForm; end; procedure TFoo.ShowForm; begin MyForm := TMyForm.Create; try MyForm.Showmodal; finally MyForm.Free; end; end; Was kann man dagegen unternehmen?
Delphi-Quellcode:
Und nun die Preisfrage: Warum ist die Verwendung von
procedure TFoo.ShowForm;
begin MyForm := TMyForm.Create; try MyForm.Showmodal; finally FreeAndNil( MyForm.Free ); end; end;
Delphi-Quellcode:
selbst unter Nicht-ARC ratsam?
FreeAndNil
Logisch: Ich zerstöre die Instanz aber hinterlasse einen ungültigen Referenz-Zeiger in
Delphi-Quellcode:
. Wer das tatsächlich so gemacht hat, hat schon immer eine Gratwanderung betrieben.
MyForm
Bei lokalen Variablen ist das wie gezeigt kein Problem, aber bei nicht lokalen Variablen war der Code schon immer grenzwertig. Auch wenn er sich nicht negativ ausgewirkt hat heisst es nicht, dass es korrekt ist. Fazit: Bei einer korrekten und robusten Programmierung ist dieser gezeigte Fall absolut kein Problem ;) |
AW: Weak Referenzen überlegungen...
Zitat:
|
AW: Weak Referenzen überlegungen...
"ShowModal" ist wie bereits gesagt kein besonders gutes Beispiel, weil unter iOS zwar unterstützt wird und dort tatsächlich auch blockiert, aber spätestens unter Android ist damit Schluss.
Zudem kann ich den Fehler, dass das Form nicht geschlossen wird, ebenfalls nicht nachstellen - zumindest nicht mit mit o.g. Code. Hast Du ein echtes Beispiel für uns, wo Dich ARC zwickt? Über ARC unter Win32 würde ich - Stand heute - nicht nachdenken. Es liegen keine belastbaren Infos vor, dass wir das in endlicher Zeit bekommen würden, vor der Art der Implementation ganz zu schweigen. Das ist reine Spekulation. |
AW: Weak Referenzen überlegungen...
Die Art der Implementation von ARC ist keine Spekulation, sondern aktuell genau so implementiert ;)
|
AW: Weak Referenzen überlegungen...
Ich meine die Überlegung, ob ARC unter Win32/Win64 - wenn es denn kommt - via Compiler-Schalter steuerbar sein könnte etc.
//edit: Zum Thema: Eigene Verrenkungen mit .DisposeOf() kann man sich sparen, wenn man das Event OnClose des betreffenden Forms ausprogrammiert und dort den Parameter "Action" auf TCloseAction.caFree setzt. Dann wird der Destruktor auch ARC-konform am Ende aufgerufen. |
AW: Weak Referenzen überlegungen...
Sorry sollte natürlich Show und nicht showmodal sein
|
AW: Weak Referenzen überlegungen...
Zitat:
Delphi-Quellcode:
Pflicht. ;)
FreeAndNil
|
AW: Weak Referenzen überlegungen...
Zitat:
Wenn man ein Fenster öffnet, nutzt man i.d.R. doch die Variable im Form. Aber das war ja nicht die Frage... |
AW: Weak Referenzen überlegungen...
Zitat:
idR heisst ja nicht, dass es korrekt ist. Korrekt ist auf jeden Fall, dass Variablen (vor allem die für Instanz-Referenzen) die nicht lokal sind niemals auf einem ungültigen Wert stehen zu lassen. Selbst unter Nicht-ARC ist das schon immer der direkte Weg zu "Torte-Im-Auge" gewesen. Ein
Delphi-Quellcode:
knallt und ist auch mit
FSomeThing.Free
Delphi-Quellcode:
nicht zu bändigen, wenn sich dort noch eine ungültige Referenz befindet. Lösen kann man das nur mit dem Setzen der Variablen auf
if Assigned( FSomeThing ) then
Delphi-Quellcode:
und dafür wurde ja extra
nil
Delphi-Quellcode:
eingeführt. Und das ist dann auch ARC-Safe.
FreeAndNil
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 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