Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Weak Referenzen überlegungen...

  Alt 26. Dez 2014, 15:01
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 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 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 FreeAndNil selbst unter Nicht-ARC ratsam?

Logisch: Ich zerstöre die Instanz aber hinterlasse einen ungültigen Referenz-Zeiger in 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
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat