delphi - Form.Release+NIL
winapi vcl (5)
De ustedes siempre pueden llamar 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 contenido a un TObject ya que no puede probar el tipo de Obj. Esto debería ser seguro ya que, como Free, Release no es virtual.
si se llama a Form.Release después de usar el formulario, liberará toda la memoria relacionada pero no establecerá la variable de forma en nil.
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 debería establecerse en cero en algún momento. De la descripción de la Versión I 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 realmente se libere el formulario. No puedo detectar cuándo finaliza Form.Release para establecer la forma var a nil.
¿Cuál es la mejor manera de hacer esto?
Holger
Como se menciona, Liberar es solo un diferido Gratis para un formulario para usar si quiere Cerrar / Libre. Aparte de diferir, 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 cero después de llamar a Free o usar FreeAndNil.
Si aún quieres usar Release, está bien. Solo establecer el valor de la variable a nil funciona. 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. Mi preferencia es usar solo Release donde realmente se necesite.
En Delphi Win32, la forma apropiada de liberar objetos es llamar
FreeAndNil(Form1)
Esto hace ambos trabajos en una sola llamada.
Sin embargo, tengo la sensación de que su pregunta es más de lo que parece. ¿Estás usando Delphi para .NET? Y si es así, ¿qué versión?
La versión es solo un (potencialmente) diferido Gratis. Lo primero que debe hacer después de llamar a Release es anotar la variable.
Entonces, estará seguro incluso si algún código intenta hacer referencia a Form1 antes de que se destruya. En un caso como en tu código, solo recrearía de forma segura otro Form1 para el nuevo uso sin molestar al que se está destruyendo.
Pon la linea
Form1 := nil;
justo después de la llamada a Release.
La versión solo publica un mensaje CM_RELEASE en el Formulario que permite que el Formulario finalice lo que hay en su cola (controladores de eventos) antes de manejar el mensaje CM_RELEASE, lo que significa que normalmente solo se llama a Free.
Por lo tanto, después de invocar Release, no debe suponer que la variable Form aún apunta a un Formulario válido, por lo que pone nil en la variable.