Domanda

se Form.Release viene chiamato dopo aver utilizzato il modulo, libererà tutta la memoria correlata ma non imposterà la variabile del modulo su zero.

if not assigned (Form1) then
  begin
    Application.CreateForm(Tform1, Form1);
    try
      // Do something
    finally
      Form1.Release
    end;
  end;

Per poter chiamare nuovamente lo stesso codice, Form1 dovrebbe essere impostato su zero a un certo punto. Dalla descrizione di Release non posso farlo

Form1 := nil;

subito dopo il rilascio, poiché la procedura di rilascio tornerà direttamente dopo essere stata chiamata e prima che il modulo venga effettivamente liberato. Non riesco a rilevare quando Form.Release ha terminato di impostare il var var su zero.

Qual è il modo migliore per farlo?

È stato utile?

Soluzione

Metti la linea

  Form1 := nil;  

subito dopo la chiamata a Release.

Rilascio sta semplicemente pubblicando un messaggio CM_RELEASE sul modulo che consente al modulo di completare ciò che è nella sua coda (gestori di eventi) prima di gestire il messaggio CM_RELEASE che normalmente significa semplicemente chiamare gratis.
Quindi, dopo aver chiamato Release, non dovresti supporre che la variabile Form rimanga puntata su un Form valido, mettendo così zero nella variabile.

Altri suggerimenti

Il rilascio è solo un (potenzialmente) differito gratuito. La prima cosa da fare dopo aver chiamato Release è il nilling della variabile.
Quindi, sarai al sicuro anche se un codice tenta di fare riferimento a Form1 prima che venga effettivamente distrutto. In un caso come nel tuo codice, ricreare in modo sicuro un altro Form1 per il nuovo utilizzo senza disturbare quello che viene distrutto.

Puoi sempre chiamarlo così:

procedure FreeOrReleaseAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  if Temp is TCustomForm then
    TCustomForm(Temp).Release
  else
    Temp.Free;
end;

Assicurati di controllare il tipo dopo il cast su un oggetto TO poiché non puoi testare il tipo di Obj. Questo dovrebbe essere sicuro poiché come Free, Release non è virtuale.

Come accennato, Release è solo un Free differito che un modulo può usare se vuole chiudere / liberare se stesso. A parte il differimento, non fa nulla di diverso da Rilascio. Quindi non è utile chiamare Release in questo esempio. La chiamata gratuita sembra essere più logica. E puoi impostarlo su zero dopo aver chiamato Free o usare FreeAndNil.

Se vuoi ancora usare Release, va bene. Basta impostare il valore della variabile su zero funziona. In questo modo il forum non si comporta diversamente. Ma ricorda che in questo caso è più efficiente e più deterministico chiamare Free invece di Release. La mia preferenza è quella di utilizzare Release solo dove è veramente necessario.

In Delphi Win32, il modo appropriato per liberare oggetti è chiamare

FreeAndNil(Form1)

Questo fa entrambi i lavori in una sola chiamata.

Tuttavia, ho la sensazione che ci sia di più nella tua domanda di quanto sembri. Stai usando Delphi per .NET - e se sì, quale versione?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top