Pregunta

si se llama a Form.Release después de usar el formulario, liberará toda la memoria relacionada pero no establecerá la variable de formulario en nulo.

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

Para poder volver a llamar al mismo código, Form1 tendría que establecerse en nulo en algún momento. De la descripción de Release que no puedo hacer

Form1 := nil;

justo después de la Liberación, porque el procedimiento de Liberación regresará directamente después de ser llamado y antes de que el formulario se libere realmente. No puedo detectar cuándo Form.Release finaliza para establecer el formulario var en nil.

¿Cuál es la mejor manera de hacer esto?

¿Fue útil?

Solución

Pon la línea

  Form1 := nil;  

justo después de la llamada a Liberar.

Lanzamiento es simplemente publicar un mensaje CM_RELEASE en el Formulario que le permite al Formulario terminar lo que está en su cola (controladores de eventos) antes de manejar el mensaje CM_RELEASE, lo que normalmente significa simplemente llamar Gratis.
Por lo tanto, después de llamar a Release, no debe suponer que la variable Form aún señala a un Formulario válido, por lo tanto, poner nil en la variable.

Otros consejos

El lanzamiento es solo un (potencialmente) diferido gratuito. Lo primero que debe hacer después de llamar a Release es anular la variable.
Entonces, estará seguro incluso si algún código intenta hacer referencia a Form1 antes de que realmente se destruya. En un caso como en su código, simplemente recrearía con seguridad otro Form1 para el nuevo uso sin molestar al que se está destruyendo.

De usted siempre podría llamar a esto:

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;

Asegúrese de verificar el tipo después de enviar a un TObject ya que no puede probar el tipo de Obj. Esto debería ser seguro ya que, como Gratis, Release no es virtual.

Como se menciona, Release es solo un Free diferido para que un formulario lo use si quiere Cerrar / Free. Aparte de ser diferido, no hace nada diferente de Release. Entonces no sirve de nada llamar a Release en ese ejemplo. Llamar gratis parece ser más lógico. Y puede configurarlo en nulo después de llamar a Free o usar FreeAndNil.

Si aún quieres usar Release, está bien. Simplemente establecer el valor variable en nil works. Hacer eso no hace que el foro se comporte de manera diferente. Pero recuerde que en este caso es más eficiente y más determinista llamar a Free en lugar de Release. Prefiero usar solo Release donde realmente se necesita.

En Delphi Win32, la forma adecuada de liberar objetos es llamar

FreeAndNil(Form1)

Esto hace ambos trabajos en una sola llamada.

Sin embargo, tengo el presentimiento de que hay más en tu pregunta de lo que parece. ¿Estás usando Delphi para .NET? Y si es así, ¿qué versión?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top