Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Cross-Platform-Entwicklung (https://www.delphipraxis.net/91-cross-platform-entwicklung/)
-   -   Delphi Weak Referenzen überlegungen... (https://www.delphipraxis.net/183272-weak-referenzen-ueberlegungen.html)

Mavarik 26. Dez 2014 13:38

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:
 MyForm := TMyForm.Create;
 try
   MyForm.Showmodal;
 finally
   MyForm.Free;
 end;
Selbst so simpler Code schließt nicht mehr das Fester, weil komischerweise die Referent nach einem Create nicht 1 ist.
Spätestens das dieser Stelle muss also ein Disposeof her.

Also folgende Procedure geschrieben...

Delphi-Quellcode:
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}
ARC hat sicherlich seine Vorteile, aber eigentlich nur, in Hinblick auf die CrossPlattform Programmierung, wenn uns ARC
@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

Sir Rufo 26. Dez 2014 14:01

AW: Weak Referenzen überlegungen...
 
Also der Code
Delphi-Quellcode:
 MyForm := TMyForm.Create;
 try
   MyForm.Showmodal;
 finally
   MyForm.Free;
 end;
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
Delphi-Quellcode:
ShowModal
kehrt erst dann zurück, wenn die Form geschlossen wurde.

(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:
ShowModal
gibt.)

Nehmen wir also mal an, der Code ist so vorhanden:
Delphi-Quellcode:
procedure Foo;
var
  MyForm : TMyForm;
begin
 MyForm := TMyForm.Create;
 try
   MyForm.Showmodal;
 finally
   MyForm.Free;
 end;
end;
dann ist das Verhalten exakt gleich. Nach dem Verlassen der Prozedur/Methode ist die erzeugte Form-Instanz aus dem Speicher verschwunden.
Delphi-Quellcode:
TFoo = class
private
  MyForm : TMyForm;
public
  procedure ShowForm;
end;

procedure TFoo.ShowForm;
begin
 MyForm := TMyForm.Create;
 try
   MyForm.Showmodal;
 finally
   MyForm.Free;
 end;
end;
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.

Was kann man dagegen unternehmen?
Delphi-Quellcode:
procedure TFoo.ShowForm;
begin
 MyForm := TMyForm.Create;
 try
   MyForm.Showmodal;
 finally
   FreeAndNil( MyForm.Free );
 end;
end;
Und nun die Preisfrage: Warum ist die Verwendung von
Delphi-Quellcode:
FreeAndNil
selbst unter Nicht-ARC ratsam?

Logisch: Ich zerstöre die Instanz aber hinterlasse einen ungültigen Referenz-Zeiger in
Delphi-Quellcode:
MyForm
. Wer das tatsächlich so gemacht hat, hat schon immer eine Gratwanderung betrieben.

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 ;)

Der schöne Günther 26. Dez 2014 14:42

AW: Weak Referenzen überlegungen...
 
Zitat:

Zitat von Mavarik (Beitrag 1284717)
Vor ARC haben wir uns keine sorgen gemacht, oder?

Eigentlich mache ich mir Sorgen, BIS ich ARC auf Windows endlich rundum habe, und nicht nur bei Records, Interfaces und Arrays :wink:

Daniel 26. Dez 2014 16:22

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.

Sir Rufo 26. Dez 2014 16:30

AW: Weak Referenzen überlegungen...
 
Die Art der Implementation von ARC ist keine Spekulation, sondern aktuell genau so implementiert ;)

Daniel 26. Dez 2014 16:48

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.

Mavarik 26. Dez 2014 16:56

AW: Weak Referenzen überlegungen...
 
Sorry sollte natürlich Show und nicht showmodal sein

Sir Rufo 26. Dez 2014 17:14

AW: Weak Referenzen überlegungen...
 
Zitat:

Zitat von Mavarik (Beitrag 1284742)
Sorry sollte natürlich Show und nicht showmodal sein

Das ändert an meiner Aussage nichts. Mit einer lokalen Variablen ist bei beiden Schluss und mit einer nicht-lokalen ist das Design falsch, denn dann ist
Delphi-Quellcode:
FreeAndNil
Pflicht. ;)

Mavarik 26. Dez 2014 21:51

AW: Weak Referenzen überlegungen...
 
Zitat:

Zitat von Sir Rufo (Beitrag 1284743)
Das ändert an meiner Aussage nichts. Mit einer lokalen Variablen ist bei beiden Schluss und mit einer nicht-lokalen ist das Design falsch, denn dann ist
Delphi-Quellcode:
FreeAndNil
Pflicht. ;)

FreeandNIL hilft auch nicht.

Wenn man ein Fenster öffnet, nutzt man i.d.R. doch die Variable im Form.

Aber das war ja nicht die Frage...

Sir Rufo 26. Dez 2014 22:09

AW: Weak Referenzen überlegungen...
 
Zitat:

Zitat von Mavarik (Beitrag 1284757)
Zitat:

Zitat von Sir Rufo (Beitrag 1284743)
Das ändert an meiner Aussage nichts. Mit einer lokalen Variablen ist bei beiden Schluss und mit einer nicht-lokalen ist das Design falsch, denn dann ist
Delphi-Quellcode:
FreeAndNil
Pflicht. ;)

FreeandNIL hilft auch nicht.

Wenn man ein Fenster öffnet, nutzt man i.d.R. doch die Variable im Form.

Aber das war ja nicht die Frage...

Welche "Variable im Form"?

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:
FSomeThing.Free
knallt und ist auch mit
Delphi-Quellcode:
if Assigned( FSomeThing ) then
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
Delphi-Quellcode:
nil
und dafür wurde ja extra
Delphi-Quellcode:
FreeAndNil
eingeführt. Und das ist dann auch ARC-Safe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 Uhr.
Seite 1 von 2  1 2      

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